3
votes

I'm trying to implement fine grained @Autowired configuration using basically the example from the spring documentation at: http://docs.spring.io/spring/docs/3.2.0.RELEASE/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers.

Given the following testcase:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes=ExampleConfiguration.class)
public class ExampleTest {

    @Autowired @ExampleQualifier(key="x")
    private ExampleBean beanWithQualifierKeyX;

    @Test
    public void test() {
        System.out.println(this.beanWithQualifierKeyX);
    }

}

and the following configuration:

@Configuration
public class ExampleConfiguration {

    @Bean
    @ExampleQualifier(key = "x")
    public ExampleBean exampleBean1() {
        return new ExampleBean();
    }

    @Bean
    @ExampleQualifier(key = "y")
    public ExampleBean exampleBean2() {
        return new ExampleBean();
    }

    @Bean
    public ExampleBean exampleBean3() {
        return new ExampleBean();
    }

}

with the custom qualifier annoation:

@Qualifier
@Retention(RetentionPolicy.RUNTIME)
public @interface ExampleQualifier {

    String key();

}

What I would expect is the following: The property beanWithQualifierKeyX should be autowired using the first bean from the configuration class. Both the annotation on the configuration and the annotation on the property have the key="x" setting so this should be the only match. As far as I can see this is almost the same as MovieQualifier annotation from the Spring example documentation.

However, when I execute the test I get the following error:

org.springframework.beans.factory.BeanCreationException: 
Could not autowire field: private xxx.ExampleBean xxx.ExampleTest.beanWithQualifierKeyX; 

nested exception is

org.springframework.beans.factory.NoSuchBeanDefinitionException: 
No unique bean of type [xxx.ExampleBean] is defined: 
expected single matching bean but found 2: [exampleBean1, exampleBean2]

It looks like Spring does perform a match against the annotation (since both exampleBean1 and exampleBean2 are annotated) but doesn't take into account the value for the key of the annotation - otherwise x would be a perfect match.

Did I miss something in the configuration process or why is there no match?

The Spring version I'm using is 3.2.0.RELEASE

1
In your custom qualifier I miss the @Target annotation and I'm not sure but instead of key try value.M. Deinum
I tried both approaches - adding @Target (field and method) as well as using value instead of key - same result, the error still persists.Christian Seifert
Have you tried injecting it into something else as a testcase? I'm wondering if this is a general issue or only a test thing.M. Deinum
Tested it localy works like a charm (used the latest 3.2.x release). Tested it again with 3.2.0 and it fails. So looks like an issue in 3.2.0. Upgrade spring version to the latest 3.2.x release.M. Deinum
Note that it also works if you use @javax.inject.Qualifier in 3.2.0.Sotirios Delimanolis

1 Answers

4
votes

There is/was an bug in Spring 3.2.0 Autowiring with @Qualifier and @Qualifier meta annotation fails in Spring 3.2 (fixed in 3.2.1)

Its description sound exactly like your problem.

So update to 3.2.1