스프링 빈을 등록하는 2가지 방법 / DI 주입 방법

2022. 5. 24. 15:36 Spring Framework/Spring 개념

스프링을 처음 사용하면 @Autowired, @Component, @Controller 등 다양한 어노테이션을 사용해야한다. 그런데 이 어노테이션들이 정확히 어떤 역할을 하는지 모르고 일단 사용하는 경우가 많이 있다.

오늘은 스프링 빈을 등록하는 2가지 방법을 알아보도록 하자.

 

1. 컴포넌트 스캔과 자동 의존관계 설정

 -> 컴포넌트 스캔의 원리는 기본적으로 @Component 어노테이션이 있으면 자동으로 스프링 빈으로 등록된다.

 참고로, @Component 어노테이션은  @Controller , @Service, @Repository를 포함한다.

 

-Controller

@Controller 
public class MemberController {

    private final MemberService memberService;
    @Autowired
    //멤버 컨트롤러가 생성이 될떄 스프링빈에 등록되어있는 멤버서비스를 주입
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

Controller에는 @Controller 어노테이션을 붙여준다.

 

 

-Service

@Service
public class MemberService {
    private final MemberRepository memberRepository;
    @Autowired 
    public MemberService(MemberRepository memberRepository) {    
   		 this.memberRepository = memberRepository; 
    }
}

 Service에는 @Service 어노테이션을 추가한다.

 

생성자에 @Autowired를 사용하면 객체 생성 시점에 스프링 컨테이너에서 해당 스프링 빈을 찾아서 주입한다. 생성자가 1개만 있으면 @Autowired는 생략할 수 있다.

 

-Repository

@Repository
public class MemoryMemberRepository implements MemberRepository {
}

Repsository에는 @Repository 어노테이션을 추가한다.

이렇게 설정하면, 스프링 컨테이너에

Controller - > Service -> Repository  구조로 ,  MemberService와  Repository가 스프링 빈으로 등록된다.

 

 

2. 자바 코드로 직접 스프링 빈 등록하기

자바 코드로 직접 등록할때도 Controller는 컨포넌트 스캔으로 올라가기 때문에 @Controller를 추가해야 한다.

@Controller
public class MemberController {

    private final MemberService memberService;
    @Autowired
    //멤버 컨트롤러가 생성이 될떄 스프링빈에 등록되어있는 멤버서비스를 주입
    public MemberController(MemberService memberService) {
        this.memberService = memberService;
    }
}

 

다음으로 Service와 Repository에  이전에 추가했던 어노테이션을 추가하는 대신에 

SpringConfig.java 라는 클래스를 하나 생성한다.

@Configuration
public class SpringConfig {

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

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

 @Configuration 어노테이션을 추가하고, 스프링 빈으로 등록하고자 하는 Service와 Repository에 @Bean 어노테이션을 추가하면, 스프링 빈으로 등록된다.

 

최근에는 어노테이션 하나로 해결되는 1번 방법이 더 많이 사용되고 있지만, 상황에 따라 2번 방법도 사용되고 있다.

->개발을 진행하다가 Repository를 변경해야 한다고 가정 했을때, 2번째 방법을 사용하면 Service나 Controller를 건드릴 필요 없이 SpringConfig에 등록된 Repository Bean만 수정해주면 간편하기 때문이다. 

 

3. 추가적으로 XML로 스프링 빈을 등록하는 방법도 있지만, 최근에는 거의 사용하지 않는다.

 

 


DI(dependency injection) 을 주입하는 3가지 방법

 

DI를 주입하는 방법에는 3가지가 있다.

 

1. 필드 주입 : 가장 짧은 코드로 구현이 가능하지만, 추후 변경할 수 있는 방법이 없기때문에 권장되지 않는다.

@Autowired
private final MemberService memberService;

 

2. Setter 주입 : Setter주입 방법의 가장 큰 단점은 public이 의무화되는 메서드에서 개발자가 임의로 호출할 수 있기 때문에 보안상의 문제와 실수로 인한 임의적인 변경 가능성이 있기 때문에 권장되지 않는다.

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

 

3. 생성자 주입 :  최근 가장 권장되는 DI주입 방식이다.

  • Null을 주입하지 않는한 NullPointException이 발생하지 않는다.
  • final 키워드를 사용하여 객체의 불변을 유지할 수 있다.
  • 개발자의 실수로 빈의 주입이 이루어지지 않았을 경우 final 키워드를 사용하면 컴파일 시점에서 오류를 잡아낼 수 있다.
  • 순환 참조를 방지할 수 있다.

 

@RequiredArgsConstructor
private final UserService userService;

 

출처 : https://1-7171771.tistory.com/105?category=885255