Spring 응용 프로그램 에서 NoUniqueBean Definition Exception 이상 해결 방안 던 지기

머리말
우 리 는 Spring 응용 프로그램 을 개발 할 때 같은 유형의 Bean 두 개 를 실수 로 주입 할 수 있 습 니 다.예 를 들 어 같은 Service 인터페이스 의 종 류 를 실현 할 수 있 습 니 다.예 를 들 어 의사 코드 는 다음 과 같 습 니 다.

interface SampleService {
  String getName();
}

class ServiceA implements SampleService{
   String getName(){
     return "john";
   }
}
class ServiceB implements SampleService{
   String getName(){
     return "wonder";
   }
}
이때 우 리 는 SampleService 인터페이스 로 주입 한다.

@Autowired
SampleService sampleService;
애플 리 케 이 션 을 시작 하면 Spring 은 다음 과 같은 오 류 를 우아 하 게 알려 줍 니 다.
Exception in thread "main" org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.john.primary.SampleService' available: expected single matching bean but found 2: ServiceA,ServiceB
하지만 우 리 는 잘못 보고 하고 싶 지 않 고 그 중 한 빈 을 얻 고 싶 습 니 다.이 럴 때 우 리 는 어떻게 해 야 합 니까?
해결 방안
같은 유형의 빈 이 두 개 포함 되 어 있 는 이상,일반적으로 우 리 는 그 중의 한 빈 을 주입 하지 않 으 면 된다.그러면 우리 가 이 두 개의 같은 유형의 빈 을 보존 하고 싶 지만,SampleService 를 정상적으로 주입 시 키 고 싶다 면?
만약 에 우리 가 초기 Spring 의 Xml 로 Bean 을 설정 할 때 다음 과 같은 두 가지 방법 으로 해결 할 수 있 습 니 다.
1.그러면 우 리 는 그 중의 빈 설정 에 autowire-candidate="false"를 추가 할 수 있 습 니 다.

<bean id="serviceA" class="com.john.primary.ServiceA" />
<bean id="serviceB" class="com.john.primary.ServiceB" autowire-candidate="false" />
2.또는 그 중의 빈 설정 에 primary="true"를 추가 합 니 다.

<bean id="serviceA" class="com.john.primary.ServiceA" primary="true"/>
<bean id="serviceB" class="com.john.primary.ServiceB" />
3.javax.annotation.Priority 주석 사용
이런 방식 은 우리 가 BeanFactory 에 dependency Comparator 를 더 해 야 한다.예제 코드 는 다음 과 같다.

DefaultListableBeanFactory beanFactory = (DefaultListableBeanFactory)context.getBeanFactory();
//@Priority    
beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
SampleService sampleService= context.getBean(SampleService.class);
4.주해 Order 를 실현 하거나 org.springframework.core.Ordered 인 터 페 이 스 를 실현 합 니 다.

public class ServiceA implements SampleService,Ordered {

  @Override
  public int getOrder() {
     return 0;
  }

  @Override
  public String toString() {
     return "ServiceA{}";
  }
}
이러한 방식 은 AnnotationAware Order Comparator 의 getPriority 방법 을 다시 써 야 합 니 다.예제 코드 는 다음 과 같 습 니 다.

public class PriorityOrderComparator extends AnnotationAwareOrderComparator {
  /**
   * Shared default instance of {@code PriorityOrderComparator}.
   */
  public static final PriorityOrderComparator INSTANCE = new PriorityOrderComparator();

  @Override
  public Integer getPriority(Object obj) {
         //   Priority
      Integer order = super.getPriority(obj);
      if(order == null)
        //  Order    Ordered     
        return  super.findOrder(obj);
      return  order;
  }
}
우 리 는 또한 현재 유행 하 는 주해 방식 을 사용 하여 실현 할 수 있다.Spring 문서 에서 도 언급 한 적 이 있다.
Because autowiring by type may lead to multiple candidates, it is often necessary to have more control over the selection process. One way to accomplish this is with Spring's @Primary annotation. @Primary indicates that a particular bean should be given preference when multiple beans are candidates to be autowired to a single-valued dependency. If exactly one primary bean exists among the candidates, it becomes the autowired value.
그러면 다음 과 같은 방식 을 사용 할 수 있다.
1.@Primary 주석:
이 주 해 는 클래스 나 방법 에 표시 할 수 있 습 니 다.예 는 다음 과 같 습 니 다.

@Primary
@Component
class ServiceA implements SampleService{
  String getName(){
    return "john";
  }
}
주 해 는@Bean 주해 가 있 는 방법 에서:

@Bean
@Primary
SampleService sampleService(){
  return new ServiceA();
}
2.Xml 설정 의 세 번 째 또는 네 번 째 해결 방안 을 사용 합 니 다.네 번 째 방안 만 사용 하면 AnnotationAware Order Comparator 를 다시 확장 해 야 합 니 다.
이상 은 Spring 응용 프로그램 에서 NoUniqueBean Definition Exception 이상 해결 방안 의 상세 한 내용 입 니 다.Spring 이상 해결 에 관 한 자 료 는 저희 의 다른 관련 글 을 주목 하 세 요!

좋은 웹페이지 즐겨찾기