[SpringBoot] #14 - 자바 코드로 직접 스프링 빈 등록하기
https://www.inflearn.com/course/%EC%8A%A4%ED%94%84%EB%A7%81-%EC%9E%85%EB%AC%B8-%EC%8A%A4%ED%94%84%EB%A7%81%EB%B6%80%ED%8A%B8/dashboard
1. 어노테이션 삭제하기
- 회원 서비스와 회원리포지토리의 어노테이션 ( @Service, @Repository, @Autowired ) 를 제거하고 진행
Controller는 그대로 둔다.
2. SpringConfig 파일 만들기
@Configuration
public class SpringConfig {
@Bean
public MemberService memberService(){
return new MemberService(memberRepository());
}
@Bean
public MemberRepository memberRepository(){
return new MemoryMemberRepository();
}
}
- 위와 같이 등록하면 Spring Bean을 등록하라는 것임을 인식하여 MemberService를 호출하여 Spring Bean을 등록 해 준다.
- MemberService는 memberRepository()를 엮어줘야하기 때문에 return new MemberService(memberRepository());
의 형태로 입력한다.
3. 장단점
- DI에는 필드 주입, Setter 주입, 생성자 주입과 같이 3가지 방법이 있음.
의존관계가 실행 중에 동적으로 변하는 경우(런타임 돌고 있는데 중간에 바뀌는 경우)는 거의 없기 때문에 생성자 주입을 권장
- 필드 주입
- 필드 주입은 수정이 어렵다.
@Controller
public class MemberController {
@Autowired private MemberService memberService;
}
- 생성자 주입
- 처음 어플리케이션이 조립되는 시점에 한 번만 들어오고 끝이 난다. (가장 권장하는 방법)
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public MemberController(MemberService memberService){
this.memberService = memberService;
}
}
- Setter 주입
- 생성은 생성대로 되고 Setter 를 이후 호출이 되어 통해 주입이 된다.
- set xx의 형태
- 누군가 MemberController를 호출 했을 때 이것이 public으로 열려 있어야하여 노출이 된다.
@Controller
public class MemberController {
private final MemberService memberService;
@Autowired
public SetMemberController(MemberService memberService){
this.memberService = memberService;
}
}
- 실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리 같은 코드는 컴포넌트 스캔을 사용하고
정형화 되지 않거나 상황에 따라 구현 클래스를 변경해야 하면 실행을 통해 스프링 빈으로 등록한다.
** 상황에 따라 구현 클래스를 변경 ?
예를들어 DB 선정이 되지 않아 Memory를 사용하다가 이후 교체 하는 등의 경우...
→ 컴포넌트 스캔을 사용하면 여러 코드를 수정해야하지만, 스프링 빈으로 등록하는 경우 기존의 코드를 하나도 손대지않고 한 번에 수정이 가능하다.
- @Autowired를 통한 DI는 helloController, MemberService 등과 같이 스프링이 관리하는 객체에서만 동작한다.
스프링 빈으로 등록하지 않고 내가 직접 생성한 객체에서는 동작하지 않는다.
: MemberService 가 Spring에 등록이 되고 spring이 관리를 해야 @Autowired가 동작한다.
예를들어 SpringConfig에서 모든 어노테이션을 주석처리하는 경우 MemberService 의 @Autowired는 동작하지 않는다.
: 내가 직접 new하여 객체를 생성하는 경우에도 @Autowired가 동작하지 않는다.