티스토리 뷰
빈 이름
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
}
-@Bean 애노테이션으로 빈을 등록할때, 해당 애노테이션이 붙은 메서드의 이름이 "myBean"이라면, 해당 빈의 이름은 "myBean"이 됩니다.
@Component
public class MyBean {
// ...
}
-@Component 애노테이션으로 빈을 등록할때, 해당 애노테이션이 붙은 클래스의 이름이 "MyBean"이라면, 해당 빈의 이름은 클래스 이름의 첫글자를 소문자로 변환한 "myBean"이 됩니다.
빈 이름 충돌
-빈 이름 충돌은 동일한 이름으로 두개 이상의 빈이 등록되는 경우를 말하며, 이로인해 스프링 컨테이너에서 빈을 구분할 수 없어서 발생하는 문제가 생깁니다. 충돌이 발생하면 에러를 발생시킵니다.
@Configuration
public class AppConfig {
@Bean
public MyBean myBean() {
return new MyBean();
}
@Bean
public MyBean myBean() {
return new MyBean();
}
}
빈 이름 변경방법
@Bean
@Configuration
public class AppConfig {
@Bean(name = "myBean1")
public MyBean myBean() {
return new MyBean();
}
@Bean(name = "myBean2")
public MyBean myBean() {
return new MyBean();
}
}
- @Bean 애노테이션에 name 속성을 사용하여 원하는 이름으로 직접 지정할 수 있습니다. 이로인해 중복된 빈 이름이 구별이 됩니다.
@Component
@Component("myBean1")
public class MyBean {
// ...
}
-Component에서도 위와 같은 코드로 원하는 이름으로 직접 지정할 수 있습니다.
빈 이름 충돌(@Component와 @Bean에서의 충돌)
@Component
public class Bean {
// ...
}
@Configuration
@ComponentScan(basePackages = {"test"})
public class AppConfig {
@Bean
public Bean bean() {
return new Bean();
}
}
위의 코드를 보면 @Component로 등록한 Bean(빈 이름="bean")와 @Bean으로 등록한 bean이 이름이 겹치는 것을 볼 수 있습니다. 같은 방식으로 선언된 bean끼리 겹치는것은 에러를 발생시켰지만, 위의 코드는 에러를 발생시키지않고 @Bean으로 수동등록한것이 우선처리되어 @Bean으로 등록된것만 빈으로 등록됩니다.
@Qualifier
빈 등록을 할때 동일한 타입의 빈이 여러 개 일때 어떤 빈을 주입해야하는지 명시적으로 지정하는 애노테이션입니다.
@Component
public class BeanA implements MyBean {
// ...
}
@Component
public class BeanB implements MyBean { //동일한 인터페이스를 구현한 두개의 클래스
// ...
}
@Component
public class MyComponent {
private MyBean myBean;
@Autowired
public MyComponent(MyBean myBean) { //동일한 타입의 빈이 여러개라 어떤걸 주입받아야하는지 모름
this.myBean = myBean;
}
}
위의 코드를 보면 BeanA와 BeanB는 둘다 같은 MyBean으로 부터 상속받은 코드입니다. 이를 빈으로 등록을 하게 되면, 둘다 같은 MyBean으로 부터 상속을 받았으므로 @Autowired를 할때 문제가 발생할 수 있습니다. 문제가 발생하는 곳을 보면 MyBean 타입으로 되어있어 BeanA도 가능하고 BeanB도 가능하여 어느것을 주입받아야하는지 모르는 상황입니다. 이러한 문제를 @Qualifier를 통해 해결할 수 있습니다.
@Component
@Qualifier("beanA")
public class BeanA implements MyBean {
// ...
}
@Component
@Qualifier("beanB")
public class BeanB implements MyBean {
// ...
}
@Component
public class MyComponent {
private MyBean myBean;
@Autowired
public MyComponent(@Qualifier("beanA") MyBean myBean) { //@Qualifier를 사용해 특정 빈 주입
this.myBean = myBean;
}
}
@Primary
-빈의 우선순위를 지정하는 어노테이션입니다. 여러개의 동일한 타입의 빈이 존재할때 @Primary 어노테이션이 적용된 빈을 주입하여 우선적으로 선택합니다.
@Service
public class UserServiceImpl1 implements UserService {
//...
}
@Service
@Primary
public class UserServiceImpl2 implements UserService {
//...
}
@Component
public class MyComponent {
private UserService userservice;
@Autowired
public MyComponent(UserService userservice) { // @Primary로 우선설정되어있는 UserServiceImpl2 주입
this.userservice = userservice;
}
}
위의 코드를 보시면 UserServiceImpl1 과 UserServiceImpl2는 서로 UserService를 구현하여 타입이 겹치지만 나중에 주입 요청이 들어왔을 때 @Primary 선언을 통하여 UserServiceImpl2가 우선적으로 선택됩니다.
List,Set,Map 사용
-@Qualifier , @Primary를 사용하지 않고, 여러개의 빈을 가지고 오는방법입니다. List,Set,Map 셋 다 여러개의 동일한 타입의 빈들을 다 가지고 올 수 있습니다.
@Component
public class MyComponent {
private List<MyBean> myBeans;
@Autowired
public MyComponent(List<MyBean> myBeans) {
this.myBeans = myBeans;
}
// ...
}
'자바 > 스프링' 카테고리의 다른 글
빈 라이프사이클 및 스코프 (0) | 2023.06.27 |
---|---|
@Autowired 자동주입 (0) | 2023.06.26 |
컴포넌트 스캔 (0) | 2023.06.26 |
WAS(Web Application Server) , DispatcherServlet (0) | 2023.06.24 |
스프링 Controller, Repositroy, Service (0) | 2023.05.30 |