0

I have the bean config:

<bean id="PostLoginUpdater" class="xyz.auth.PostLoginUpdater" autowire="byType" />

and

public class PostLoginUpdater implements PostLoginStatePersonalizer {

    //@Qualifier("CustomerManager")
    @Inject
    //@Resource(name = "CustomerManager")      
    private CustomerManager customerManager;

    public void setCustomerManager(CustomerManager customerManager)
    {
        this.customerManager = customerManager;
    }
}

Because there are two beans that implement CustomerManager I get this error:

No unique bean of type [CustomerManager] is defined: expected single matching bean but found 2

As you can see, I'v tried several combinations (@Inject along with @Qualifier, @Ressource, only @Qualifier) But I don't get rid of this error message.

According to Spring In Depth, @Qualifier can be used along with @Inject. Can't I used them together if I defined autowire="byType" in bean config?

And I don't use <context:annotation-config /> or <context:component-scan />

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
GarfieldKlon
  • 11,170
  • 7
  • 31
  • 33

3 Answers3

1

You should be able to use a combination of '@Inject' and '@Qualifier', if you have multiple beans of the same type. Here is how to configure it -

    <bean id="PostLoginUpdater" class="xyz.auth.PostLoginUpdater" autowire="byType" />
<bean id="firstManager" class="xyz.manager.CustomerManager" autowire="byType" >
    <qualifier>first</qualifier>
</bean>
<bean id="secondManager" class="xyz.manager.CustomerManager" autowire="byType" >
    <qualifier>second</qualifier>
</bean>

If you had two beans of type 'CustomerManager' as shown above, you could use the snippet shown below for injection -

 public class PostLoginUpdater implements PostLoginStatePersonalizer {

    @Inject
    @Qualifier("first")
    private CustomerManager customerManager;

    public void setCustomerManager(CustomerManager customerManager)
    {
        this.customerManager = customerManager;
    }
}

Also, on a side note -

If you keep using one of the beans more often than another you could use the 'primary' attribute.

For example, in the above example, if you always tend to use 'firstManager', you could mark it as primary as shown below.

<bean id="PostLoginUpdater" class="xyz.auth.PostLoginUpdater" autowire="byType" />
    <bean id="firstManager" class="xyz.manager.CustomerManager" autowire="byType" primary="true" >
    </bean>
    <bean id="secondManager" class="xyz.manager.CustomerManager" autowire="byType" >
        <qualifier>second</qualifier>
    </bean>

If you have above configuration, the following code will always injects 'firstManager' when no qualifier is used -

public class PostLoginUpdater implements PostLoginStatePersonalizer {

    @Inject
    private CustomerManager customerManager;

    public void setCustomerManager(CustomerManager customerManager)
    {
        this.customerManager = customerManager;
    }
}
Sashi
  • 1,977
  • 16
  • 15
  • Unfortunately that didn't work. And `` isn't necessary [SpringDoc](http://static.springsource.org/spring/docs/3.0.x/spring-framework-reference/html/beans.html#beans-autowired-annotation-qualifiers) . I'll explicitly inject the properties, facing too many problems with autowiring in the last few days. – GarfieldKlon Nov 05 '12 at 08:40
0

It doesn't make any sense to try to autowire by type, and simultaneously specify a name. Choose one approach or the other.

artbristol
  • 32,010
  • 5
  • 70
  • 103
  • That, of course, would be too limiting. The `autowire` attribute specifies a default only that can be overridden for each property. – Michael Piefel Nov 02 '12 at 18:18
0

I have also had trouble in the past trying to use @Qualifier with @Inject. One thing to note is that there are two annotations with that name, one in Spring and one in Java:

org.springframework.beans.factory.annotation.Qualifier
javax.inject.Qualifier

However, if using the spring framework one, then the suggested usage is to explicitly name your component via @Component or @Named [@Component("beanName")] (if annotated), or in the <bean> definition. Be aware that autowiring wants the bean name, not the Class name as in your example (i.e. do not use "CustomerManager"). For example, if you have two bean definitions like in Sashi's example:

<bean id="firstManager" class="xyz.manager.CustomerManager" autowire="byType" >
    <qualifier>first</qualifier>
</bean>
<bean id="secondManager" class="xyz.manager.CustomerManager" autowire="byType" >
    <qualifier>second</qualifier>
</bean>

then declare the field like this:

@Inject
@Qualifier("firstManager") 
private CustomerManager customerManager;
pmhargis
  • 713
  • 6
  • 7
  • Here is another good Spring reference for using @Qualifier with other annotations [here](http://blogs.sourceallies.com/2011/08/spring-injection-with-resource-and-autowired/) – pmhargis Sep 04 '13 at 17:52