개발 공부 기록/02. Spring Boot

스프링 컨테이너를 다루는 방법

박세류 2023. 12. 10. 15:15
스프린 컨테이너에 빈을 등록하는 방법, 가져오는 방법에 대해 알아보자

빈을 등록하는 방법

@Service, @Repository, @Controller 말고도 다음 두개의 어노테이션을 활용해 스프링 빈으로 등록할 수 있다.

  1. @Configuration: 클래스에 붙이는 어노테이션으로, @Bean을 사용할 때 함께 사용해 주어야 한다.
  2. @Bean: 메소드에 붙이는 어노테이션, 메소드에서 반환되는 객체를 스프링 빈에 등록한다.

 

아래 예시 코드를 보자.

@Repository
public class UserRepository {

}

원래는 위와 같이 @Repository 어노테이션을 통해 빈으로 등록한다. 허나

 

@Configuration
public class UserConfiguration {

    @Bean
    public UserRepository userRepository() {
        return new UserRepository();
    }
}

와 같이 @Configuration과 @Bean 어노테이션으로도 이를 대체하여 UserRepository 클래스를 빈으로 등록 할 수 있다.

 

그렇다면 언제 @Repository나 @Service를 사용하고, 언제 @Configuration + @Bean을 사용해야 할까?

=> 주로 @Service나 @Reposiory는 개발자가 직접 만든 클래스를 빈으로 등록할 때 사용하고,

외부 라이브러리나 프레임워크에서 (JdbcTemplate 등) 가져온 클래스를 빈으로 등록할때 @Configuration + @Bean 조합을 많이 사용한다.

그러므로 위에 제시한 코드에는 @Repository 어노테이션을 적용하는게 일반적으로 맞는 케이스이다.

 

 

빈을 주입받는 방법

  1. 생성자를 이용해 주입받는 방법 (권장)
    @Repository
    public class UserRepository {
    
        private final JdbcTemplate jdbcTemplate;
    
    	// 생성자에 JdbcTemplate가 있으므로 스프링 컨테이너가 넣어준다.
        public UserRepository(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
    }
    스프링 빈을 주입받는 방법 중 가장 권장된다. @Autowired를 원래 붙여야 했으나 스프링 버전이 업데이트 되면서 생성자 방식일때는 바로 주입되도록 변경되었다.  
  2. setter + @Autowired로 주입받는 방법
    @Repository
    public class UserRepository {
    
        private JdbcTemplate jdbcTemplate;
    
        @Autowired
        public void setJdbcTemplate(JdbcTemplate jdbcTemplate) {
            this.jdbcTemplate = jdbcTemplate;
        }
     }
    final keyword가 없어야 하고(setter로 값을 넣어줘야 하니까) @Autowired 어노테이션을 붙여줘야 한다.
  3. 필드에 직접적으로 주입하는 방법.
@Repository
public class UserRepository {

    @Autowired
    private JdbcTemplate jdbcTemplate;
}

=> setter 방식은 setter를 사용하면 인스턴스가 교체당해 문제가 생길 수 있고,

@Autowired 방식은 테스트코드로 단위테스트가 어렵다. 그래서 생성자 방식이 권장된다.

  

 

@Qualifier 어노테이션

@Primary 어노테이션이 없는 상황에서 주입받는 쪽에서 특정 스프링 빈을 선택할 수 있게 해준다.

 

@Primary보다 우선순위가 높게 간주한다.

 

@Service
public class BookService {
    private final BookRepository bookRepository;

    public BookService(@Qualifier("test") BookRepository bookRepository) {
        this.bookRepository = bookRepository;
    }
}

 

이런식으로 사용한다.

반응형