티스토리 뷰

자바/스프링

빈(Bean) 등록 심화

tioon 2023. 6. 26. 20:27
빈 이름
@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
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/02   »
1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28
글 보관함