복붙노트

[SPRING] Spring 4.1 @Qualifier가 작동하지 않습니다.

SPRING

Spring 4.1 @Qualifier가 작동하지 않습니다.

클래스, XML 구성 파일 및 오류 스택 추적이 있습니다. @Qualifier가 작동하지 않는 이유를 모르겠습니다. 나는 그가 아무 것도하지 않는다는 오류를 봅니다.

public class SimpleDog implements Dog {
    @Autowired
    @Qualifier("small")
    private Size size;
    private String name;

public Size getSize() {
    return size;
}

public void setSize(Size size) {
    this.size = size;
}

public String getName() {
    return name;
}

public void setName(String name) {
    this.name = name;
}

@Override
public void giveSound() {
    System.out.println("dog size is : width : (" + size.getWidth() + ") , height : (" + size.getHeight() + ")");
    System.out.println("dog's name : " + name);
}

}

시험 등급

public class Test2 {
public static void main(String[] args) {
    ApplicationContext context = new ClassPathXmlApplicationContext("spring-test2.xml");
    SimpleDog dog = (SimpleDog) context.getBean("dog");
    dog.giveSound();
}

}

spring.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">

    <bean id="dog" class="com.tests.test2.SimpleDog">
         <property name="name" value="Puppy" />
    </bean>

    <bean id="size1" class="com.tests.test2.Size">
        <qualifier value="small"/>
        <property name="height" value="2"/>
        <property name="width" value="1"/>
    </bean>

    <bean id="size2" class="com.tests.test2.Size">
        <qualifier value="large"/>
        <property name="height" value="20"/>
        <property name="width" value="10"/>
    </bean>

    <bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
</beans>

오류 스택 추적

WARNING: Exception encountered during context initialization - cancelling refresh attempt
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dog': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
    at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
    at pl.patrykgryta.test2.Test2.main(Test2.java:12)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 18 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1016)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
    ... 20 more

Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dog': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:334)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1204)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:476)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:302)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:229)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:298)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:725)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:757)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:480)
    at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:140)
    at org.springframework.context.support.FileSystemXmlApplicationContext.<init>(FileSystemXmlApplicationContext.java:84)
    at pl.patrykgryta.test2.Test2.main(Test2.java:12)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:483)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.tests.test2.Size com.tests.test2.SimpleDog.size; nested exception is org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:555)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:331)
    ... 18 more
Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1016)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:904)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:527)
    ... 20 more

도움이 필요하다

해결법

  1. ==============================

    1.@Qualifier는 이름 또는 ID로 빈을 참조하는 데 사용됩니다. 이름이나 ID가 'small'인 xml 항목을 찾을 수 없으므로 유형별로 일치를 시도합니다. 유형 중 두 인스턴스를 찾았습니다.

    @Qualifier는 이름 또는 ID로 빈을 참조하는 데 사용됩니다. 이름이나 ID가 'small'인 xml 항목을 찾을 수 없으므로 유형별로 일치를 시도합니다. 유형 중 두 인스턴스를 찾았습니다.

    다음과 같이 작동합니다.

      <bean id="small" class="com.tests.test2.Size">      
        <property name="height" value="2"/>
        <property name="width" value="1"/>
    </bean>
    

    Size의 인스턴스를 미리 구성된 Bean으로 취급하고 싶습니다. 그렇다면 XML 파일에서 Dog의 인스턴스를 선언하고 Size beans ...를 참조 할 수 있습니다.

      <bean id="rex" class="com.tests.test2.SimpleDog">
         <property name="name" value="Puppy" />
         <property name="size" ref="size1"/>
      </bean>
    
  2. ==============================

    2.ApplicationContext의 BeanFactory가 QualifierAnnotationAutowireCandidateResolver 대신 기본 AutowireCandidateResolver (예 : SimpleAutowireCandidateResolver)로 구성되었을 가능성이 있습니다.

    ApplicationContext의 BeanFactory가 QualifierAnnotationAutowireCandidateResolver 대신 기본 AutowireCandidateResolver (예 : SimpleAutowireCandidateResolver)로 구성되었을 가능성이 있습니다.

    이전 버전의 Spring (4.0 이전)에서는 대부분의 ApplicationContext를 생성하는 동안 QualifierAnnotationAutowireCandidateResolver가 설정되었습니다 (AbstractRefreshableApplicationContext.customizeBeanFactory (DefaultListableBeanFactory) 구현을 비교하십시오).

    현재 AppCtx의 QualifierAnnotationAutowireCandidateResolver는 다음에 의해 적용될 수 있습니다 :

  3. ==============================

    3.@Qualifier (name = "..") 어노테이션을 작성하고 Spring이 삽입하기를 원하는 빈의 이름을 지정한다.

    @Qualifier (name = "..") 어노테이션을 작성하고 Spring이 삽입하기를 원하는 빈의 이름을 지정한다.

    콩 이름은 size1과 size2입니다.

    그래서 시도해보십시오.

       @Qualifier("size1")
    
  4. ==============================

    4.@Qualifier ( "small")는 "small"이라는 bean을 찾습니다 (bean id = "small"...). @Autowired는 일치하는 유형의 bean을 찾는다는 것을 의미합니다.

    @Qualifier ( "small")는 "small"이라는 bean을 찾습니다 (bean id = "small"...). @Autowired는 일치하는 유형의 bean을 찾는다는 것을 의미합니다.

    어떤 경우에는이 두 구성을 함께 사용하는 것이 좋습니다. 이는 다음과 같은 의미입니다. 이름이 비슷한 bean을 찾고, 찾지 못하면 올바른 유형의 bean을 찾으십시오. 이것은 매우 강력 할 수 있습니다.

    Spring 문서에서 xml 한정자를 사용하여 누가 "작다"를 선언 할 수있다. 그러나 그들의 예에서는 NO id = "..."입니다. 한정자와 id를 모두 정의하는 것이 합리적인지는 알 수 없습니다. 그래서 나는 (나는 테스트하지 않는다) 당신이 부품을 제거함으로써 당신의 예제를 수리 할 수 ​​있다고 가정한다. id = "sizeX"

  5. ==============================

    5.귀하의 stacktrace 말한다

    귀하의 stacktrace 말한다

    Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type [com.tests.test2.Size] is defined: expected single matching bean but found 2: size1,size2
    

    Spring은 사용할 수있는 빈 2 개를 찾을 수 있기 때문에 삽입 할 단일 빈과 일치 할 수 없습니다.이 이유 때문에이 예외가 발생합니다.

    예외 참조

    어쨌든 당신은 id = "small"인 bean이 없기 때문에이 방법을 잘못된 방법으로 사용하고 있습니다.

    @Qualifier ( "small")를 @Qualifier ( "size1") 또는 @Qualifier ( "size2")로 변경해야합니다.

  6. ==============================

    6.Spring 4.x에서는 다음 XML 스키마로 작업해야한다.

    Spring 4.x에서는 다음 XML 스키마로 작업해야한다.

    xmlns="http://www.springframework.org/schema/beans"
               xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
               xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
            http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd"
    

    다음 태그를 추가해야합니다.

    <context:component-scan base-package="com.tests.test2" />
    

    따라서 다음 XML은 문제를 해결해야합니다 (문제가 해결되었습니다 :).

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:context="http://www.springframework.org/schema/context"
           xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
        http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.0.xsd">
    
        <context:component-scan base-package="com.tests.test2" />
    
        <bean id="dog" class="com.tests.test2.SimpleDog">
           <property name="name" value="Puppy" />
        </bean>
    
        <bean id="size1" class="com.tests.test2.Size">
            <qualifier value="small"/>
            <property name="height" value="2"/>
            <property name="width" value="1"/>
        </bean>
    
        <bean id="size2" class="com.tests.test2.Size">
            <qualifier value="large"/>
            <property name="height" value="20"/>
            <property name="width" value="10"/>
        </bean>
    </beans>
    

    자세한 내용은 여기를 참조하십시오.

  7. ==============================

    7.우리는 프로젝트에서 스프링 3.x와 함께 사용되는 스트럿츠 1.x를 가지고있다. 스프링 3에서 4로 업그레이드하는 과정에서 struts 액션의 한정자 주석은 더 이상 작동하지 않습니다. 스프링 3과 4를 파고 비교 한 결과 마침내 그 이유가 발견되었습니다.

    우리는 프로젝트에서 스프링 3.x와 함께 사용되는 스트럿츠 1.x를 가지고있다. 스프링 3에서 4로 업그레이드하는 과정에서 struts 액션의 한정자 주석은 더 이상 작동하지 않습니다. 스프링 3과 4를 파고 비교 한 결과 마침내 그 이유가 발견되었습니다.

    reason1 : 봄 4에서 QualifierAnnotationAutowireCandidateResolver가 기본 리졸버가 아닙니다.

    Spring 3에서는 애플리케이션 컨텍스트에서 beanfacotry를 생성 한 후 Spring은 명시 적으로 다음을 호출한다.

    beanFactory.setAutowireCandidateResolver(new QualifierAnnotationAutowireCandidateResolver());
    

    Spring 4에서는 AbstractRefreshableApplicationContext에서 더 이상 호출되지 않습니다.

    protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory)
    

    따라서 부모 (루트) 컨텍스트의 경우 config xml이있는 경우 그대로 작동해야합니다. 그러나 자식 컨텍스트의 경우 기본 확인자는 'SimpleAutowireCandidateResolver'가됩니다.

    reason2 : Spring 4의 DefaultListableBeanFactory에서 'isAutowireCandidate ()'를 결정하려고 할 때 자식 분석기가 부모에게 전달됩니다.

    isAutowireCandidate ()는 결정을 내릴 수없는 경우 부모 beanFactory에 책임을 위임합니다.

    Spring 3에서 위임은 부모 컨텍스트가 자신의 해결자를 사용하여 isAutowireCandidate ()를 호출하도록 해석자를 부모에게 전달하지 않습니다. 그러나 Spring 4에서는 변경됩니다. 해결자가 isAutowireCandidate ()를 호출하기 위해 부모를 매개 변수로 전달됩니다. 부모도 QualifierAnnotationAutowireCandidateResolver를 Resolver로 확장 한 ContextAnnotationAutowireCandidateResolver를 가지고 있지만 여전히 도움이되지 않습니다.

    @ a5phyx 솔루션은 하위 응용 프로그램 컨텍스트 xml에 추가되는 경우 작동해야합니다.

  8. ==============================

    8.beans.xml 파일에서이 bean 정의를 사용해보십시오 :

    beans.xml 파일에서이 bean 정의를 사용해보십시오 :

    <?xml version="1.0" encoding="UTF-8"?>
    <beans xmlns="http://www.springframework.org/schema/beans"
        xmlns:security="http://www.springframework.org/schema/security"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.springframework.org/schema/beans
            http://www.springframework.org/schema/beans/spring-beans.xsd
            http://www.springframework.org/schema/security
            http://www.springframework.org/schema/security/spring-security.xsd
            http://www.springframework.org/schema/context
            http://www.springframework.org/schema/context/spring-context.xsd"
            xmlns:context="http://www.springframework.org/schema/context">
    
        <context:annotation-config/>
        <!-- define your beans here-->
    </beans>
    
  9. from https://stackoverflow.com/questions/26426694/spring-4-1-qualifier-doesntwork by cc-by-sa and MIT license