Spring中的Qualifier应用

应用

 

@Qualifier可以用来让程序员明确指定想要指定哪个bean,那有程序员就会想问,它和@Autowired和@Resource的区别是什么?

假设有如下bean定义:

    <bean id="user0" class="com.luban.entity.User">
        <property name="name" value="user0000"/>
    </bean>

    <bean id="user1" class="com.luban.entity.User" >
        <property name="name" value="user1111"/>
    </bean>

    <bean name="userService" class="com.luban.service.UserService" autowire="constructor"/>

user0和user1的类型都是user,

UserService的通过构造方法自动注入。

 

public class UserService {

    private User user;

    public UserService(User user11) {
        this.user = user11;
    }

    public void test() {
        System.out.println(user.getName());
    }
}

main方法:

    public static void main(String[] args) {
        ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring.xml");

        UserService userService = applicationContext.getBean("userService", UserService.class);
        userService.test();
    }

 

现在运行main方法,会启动Spring,会报错:

Caused by: org.springframework.beans.factory.NoUniqueBeanDefinitionException: No qualifying bean of type 'com.luban.entity.User' available: expected single matching bean but found 2: user0,user1
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveNotUnique(DependencyDescriptor.java:223)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1324)
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1255)
    at org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:939)
    at org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:842)
    ... 15 more

 

很明显,因为UserService会根据构造方法自动注入,会先根据构造方法参数类型User是找bean,找到了两个,一个user0, 一个user1,然后会根据构造方法参数名user11去进行过滤,但是过滤不出来,最终还是找到了两个,所以没法进行自动注入,所以报错。

怎么办?

要么给其中某个bean设置primary为true,表示找到多个时默认用这个。

或者给某个bean设置autowire-candidate为false,表示这个bean不作为自动注入的候选者。

还有一种就是@Qualifier, 首先,给两个bean分别定义一个qualifier:

    <bean id="user0" class="com.luban.entity.User" autowire-candidate="false">
        <property name="name" value="user0000"/>
        <qualifier value="user00"/>
    </bean>

    <bean id="user1" class="com.luban.entity.User" >
        <property name="name" value="user1111"/>
        <qualifier value="user11"/>
    </bean>

同时在UserService中使用@Qualifier注解:

public UserService(@Qualifier("user00") User user11) {
        this.user = user11;
    }

 

还需要做一件事情,因为我们是使用的XML的方式使用Spring,所以还需要添加:

<context:annotation-config/>

这样@Qualifier注解才会生效,这样配置之后UserService中的user属性就会被赋值为@Qualifier("user00")所对应的user0这个bean。

@Qualifier注解是在使用端去指定想要使用的bean,而autowire-candidate和primary是在配置端。

@Qualifier的另外一种用法

定义一个:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface Genre {

    String value();
}

修改bean的定义

    <bean id="user0" class="com.luban.entity.User">
        <property name="name" value="user0000"/>
        <qualifier type="com.luban.annotation.Genre" value="user00"/>
    </bean>

    <bean id="user1" class="com.luban.entity.User" >
        <property name="name" value="user1111"/>
        <qualifier type="com.luban.annotation.Genre" value="user11"/>
    </bean>

 

UserService中使用Genre注解:

public class UserService {

    private User user;

    public UserService(@Genre("user00") User user11) {
        this.user = user11;
    }

    public void test() {
        System.out.println(user.getName());
    }
}

这种用法相当于自定义@Qualifier注解,使得可以处理更多的情况。

同样,还可以这么做,定义两个注解:

@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("random")
public @interface Random {

}
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier("roundRobin")
public @interface RoundRobin {
    
}

注意,是在自定义的Qualifier注解上指定了名字,这样就是可以直接使用自定义注解,而不用指定名字了。比如先修改bean的定义:

    <bean id="user0" class="com.luban.entity.User">
        <property name="name" value="user0000"/>
        <qualifier type="com.luban.annotation.Random"/>
    </bean>

    <bean id="user1" class="com.luban.entity.User" >
        <property name="name" value="user1111"/>
        <qualifier type="com.luban.annotation.RoundRobin"/>
    </bean>

 

UserService中就可以这么用:

    public UserService(@RoundRobin User user11) {
        this.user = user11;
    }

 

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值