# 자바 코드로 직접 스프링 빈 등록하기
직접 설정 파일을 등록하는 방법이다.

![스프링-컨테이너](https://user-images.githubusercontent.com/68052095/102889452-08514f00-449e-11eb-8317-8b56a7c7f88a.PNG)

---

## @Configuration, @Bean
- 스프링이 실행될 때 `@Configuration` 어노테이션이 붙은 클래스를 읽고 `@Bean`이 선언된 메서드를 확인한다.
- 다음으로 확인한 메서드(`@Bean` 어노테이션이 선언되어 있는)를 호출해서 해당 메서드의 로직을 호출해서 스프링 빈에 등록해준다.
- 이후 의존관계 주입을 할 때 등록된 빈을 사용하게 한다.
- `Controller`의 경우는 어차피 스프링이 관리를 하기때문에 `@Controller`를 그대로 둔다. 또한 컴포넌트 스캔이기 때문에 `@Autowired` 어노테이션을 사용한다(다른 곳에서 설정할 수 있는게 아니므로).

---

## 참고

### `DI`에는 `필드 주입`, `setter 주입`, `생성자 주입`의 3가지 방법이 있다.

#### 필드 주입
- 스프링을 사용할 때만 넣어주고 이후에 변경할 수 있는 방법이 없으므로 권장하지 않는다.
    
#### setter 주입(setter 메서드에 @Autowired 선언)
- `setter`를 통해서 의존성이 주입된다.
- 생성은 생성대로 되고 `setter`를 나중에 호출해서 의존성을 주입해준다.
- 단점은 누군가가 호출했을 때 `public`으로 열려있어야 한다(처음에 세팅이 되어있으면 중간에 바꿀 일이 없는데 노출이 되어있기 때문에 잘못 변경하면 문제가 발생할 수 있다).

#### 생성자 주입(가장 권장하는 방법)
- 처음에 애플리케이션이 조립(세팅)될 때 생성자로 의존성이 주입되고 끝난다(이후 변경이 불가능하게 막을 수 있다).
- 의존관계가 실행중에 동적으로 변하는 경우는 거의 없으므로 생성자 주입을 권장한다.

### 컴포넌트 스캔 vs 직접 자바코드로 설정파일 만들어서 빈 등록하기
- 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용한다. **그리고 정형화되지 않거나, 상황에 따라 구현 클래스를 변경해야 하면 설정을 통해 스프링 빈으로 등록한다.**

직접 설정파일을 만들어서 등록하면 설정파일만 수정하면 다른 코드를 전혀 수정할 필요 없이 변경점을 적용할 수 있다.

### 주의
- `@Autowired` 를 통한 `DI`는 helloConroller , memberService 등과 같이 스프링이 관리하는 객체에서만 동작한다.
- 스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
- 직접 `new`로 인스턴스를 생성하는 경우에도 `@Autowired`가 동작하지 않는다(스프링 컨테이너에 올라가지 않았기 때문).

---