오늘은 몰랐으면 내일은 알면 된다

[Spring 입문] 10. 스프링빈과 의존관계 (2) 자바 코드로 직접 스프링 빈 등록하기 본문

Java/Spring

[Spring 입문] 10. 스프링빈과 의존관계 (2) 자바 코드로 직접 스프링 빈 등록하기

마스터피쓰 2022. 9. 26. 14:52

먼저 9.에서 등록해놓았던 @Service 와 @Repository 어노테이션을 모두 지우고, SpringApplication 이 있는 곳에 SpringConfig를 생성한다. 그리고 @Configuration 어노테이션을 붙인다.

 

@Configuration
public class SpringConfig {

 

@Bean 어노테이션을 붙여서 memberService 를 리턴하는 메서드를 작성해본다.

 

    @Bean
    public MemberService memberService() {
        return new MemberService();
    }

 

MemberService 같은 경우에는 생성자에 Repository가 필요하다. 따라서 Repository 메서드도 만들어준다.

 

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }

 

총 코드가 다음과 같이 되었다.

 

@Configuration
public class SpringConfig {

    @Bean
    public MemberService memberService() {
        return new MemberService(memberRepository());
    }

    @Bean
    public MemberRepository memberRepository() {
        return new MemoryMemberRepository();
    }
}

 

 

DI에는 세가지 방법이 있다. 하나는 위의 방식대로 생성자를 통해서 주입하는 방식이다. 코드는 아래와 같은 방식이다.

MemberController 생성자를 통해 MemberService 가 DI되고있다.

 

@Controller
public class MemberController {
    private final MemberService memberService;

    @Autowired
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

 

또 다른 방식은 필드 주입이다. 그런데 딱히.. 안쓴다고 하니까 참고만 하자.

 

@Controller
public class MemberController {
    @Autowired
    private final MemberService memberService;
}

 

세번째 방식은 setter를 사용하는 방식이다. 이 방식의 문제점은 setter가 public 이어야하기 때문에 중간에 다른 곳에서 호출되어 memberService가 원치않는 방식으로 바뀔 가능성이 있다는 것이다.

 

@Controller
public class MemberController {

    private MemberService memberService;

    @Autowired
    public void setMemberService(MemberService memberService) {
        this.memberService = memberService;
    }
 }

 

그래서 가장 권장되는 방식은 생성자를 통해서 주입되는 방식이라고 한다.

 

실무에서는 주로 정형화된 컨트롤러, 서비스, 리포지토리는 컴포넌트 스캔을 사용하고,

정형화되지 않고 상황에 따라 구현 클래스를 변경해야하면 설정을 통해 스프링 빈으로 등록한다.

 

repository의 경우 현재 정해져있지 않기 때문에 향후에 DB가 정해지면 repository 생성자를 해당 객체로 변경해야하는데, 이때 직접 스프링빈을 등록하게 되어있는 경우에는 다른 코드를 전혀 만지지 않고서도 간단하게 예를들어 new MemoryMemberRepository() 를 new JDBCMemoryRepository() 로 바꿀 수 있게 된다.