30 Spring自动装配@Qualifier实例

在Spring中,@Qualifier的意思是,Bean有资格自动装配上到一个字段。请参见以下情形:

自动装配示例

参见下面的例子,它会自动装配“person” bean 到 customer 的 person 属性。

package com.gp6.autoAssemblyBean.qualifier;

import org.springframework.beans.factory.annotation.Autowired;

public class Customer {
    @Autowired
    private Person person;
    
    private int type;
    private String action;
    
    public Person getPerson() {
        return person;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public String getAction() {
        return action;
    }
    public void setAction(String action) {
        this.action = action;
    }
}


但是,两个类似的 bean “com.gp6.autoAssemblyBean.qualifier.Person” 在 bean 配置文件中声明。Spring会知道哪个person bean应当自动装配?




<!-- 直接包含 AutowiredAnnotationBeanPostProcessor -->
<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-2.5.xsd">

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

    <bean id="CustomerBean" class="com.gp6.autoAssemblyBean.qualifier.Customer">
        <property name="action" value="buy" />
        <property name="type" value="1" />
    </bean>

    <bean id="PersonBean1" class="com.gp6.autoAssemblyBean.qualifier.Person">
        <property name="name" value="gp6" />
        <property name="address" value="address 123" />
        <property name="age" value="28" />
    </bean>
    
    <bean id="PersonBean2" class="com.gp6.autoAssemblyBean.qualifier.Person">
        <property name="name" value="gp6" />
        <property name="address" value="address 123" />
        <property name="age" value="28" />
    </bean>
    
</beans>

当你运行上面的例子,它产生以下异常:

log4j:WARN No appenders could be found for logger (org.springframework.core.env.StandardEnvironment).
log4j:WARN Please initialize the log4j system properly.
log4j:WARN See http://logging.apache.org/log4j/1.2/faq.html#noconfig for more info.
Exception in thread "main" org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'CustomerBean': Injection of autowired dependencies failed; nested exception is org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.gp6.autoAssemblyBean.qualifier.Person com.gp6.autoAssemblyBean.qualifier.Customer.person; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.gp6.autoAssemblyBean.qualifier.Person] is defined: expected single matching bean but found 2: [PersonBean1, PersonBean2]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:287)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1106)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:517)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:456)
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:294)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:225)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:291)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:193)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:585)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:913)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:464)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:139)
    at org.springframework.context.support.ClassPathXmlApplicationContext.<init>(ClassPathXmlApplicationContext.java:83)
    at com.gp6.autoAssemblyBean.qualifier.Test.main(Test.java:8)
Caused by: org.springframework.beans.factory.BeanCreationException: Could not autowire field: private com.gp6.autoAssemblyBean.qualifier.Person com.gp6.autoAssemblyBean.qualifier.Customer.person; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.gp6.autoAssemblyBean.qualifier.Person] is defined: expected single matching bean but found 2: [PersonBean1, PersonBean2]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:506)
    at org.springframework.beans.factory.annotation.InjectionMetadata.inject(InjectionMetadata.java:87)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor.postProcessPropertyValues(AutowiredAnnotationBeanPostProcessor.java:284)
    ... 13 more
Caused by: org.springframework.beans.factory.NoSuchBeanDefinitionException: No unique bean of type [com.gp6.autoAssemblyBean.qualifier.Person] is defined: expected single matching bean but found 2: [PersonBean1, PersonBean2]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:800)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:707)
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.inject(AutowiredAnnotationBeanPostProcessor.java:478)
    ... 15 more

@Qualifier示例

要解决上述问题,需要使用 @Quanlifier 告诉Spring哪些bean应当自动装配。

package com.gp6.autoAssemblyBean.qualifier;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;

public class Customer {
    @Autowired
    @Qualifier("PersonBean1")
    private Person person;
    
    private int type;
    private String action;
    
    public Person getPerson() {
        return person;
    }
    public void setPerson(Person person) {
        this.person = person;
    }
    public int getType() {
        return type;
    }
    public void setType(int type) {
        this.type = type;
    }
    public String getAction() {
        return action;
    }
    public void setAction(String action) {
        this.action = action;
    }
}


    原文作者:小_伙
    原文地址: https://www.jianshu.com/p/bca0fb1e182c
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞