概述
在日常开发中经常遇到会注册多个相同类型的Bean到Spring容器中,在注入时,通常会选取其中一个Bean来使用,使用@Autowired和@Qualifier注解可以解决这一问题,示例
@Autowired
@Qualifier("user1")
private User user;
上述代码就是使用@Qualifier注解指明要注入哪个Bean
实现Bean逻辑分组
@Qualifier不仅能实现注入指定Bean,标注在Bean上面还能实现Bean的逻辑分组,这样在注入的时候可以根据分组获取,如下:
实体类 User
public class User {
private Long id;
private String name;
// ...省略getter,setter和toString 方法
}
演示
public class QualifierAnnotationDependencyInjectionDemo {
@Autowired
private List users;
@Autowired
@Qualifier
private List usersQualifier;
@Autowired
@Qualifier("user2")
private User user;
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(QualifierAnnotationDependencyInjectionDemo.class);
applicationContext.refresh();
QualifierAnnotationDependencyInjectionDemo bean = applicationContext.getBean(QualifierAnnotationDependencyInjectionDemo.class);
System.out.println(bean.users);
// outputs: [User{id=1, name='null'}, User{id=2, name='null'}, User{id=3, name='null'}, User{id=4, name='null'}]
System.out.println(bean.usersQualifier);
// outputs: [User{id=3, name='null'}, User{id=4, name='null'}]
System.out.println(bean.user);
// outputs: User{id=2, name='null'}
applicationContext.close();
}
@Bean
public User User1() {
return createUser(1L);
}
@Bean
public User user2() {
return createUser(2L);
}
@Bean
@Qualifier
public User user3() {
return createUser(3L);
}
@Bean
@Qualifier
public User user4() {
return createUser(4L);
}
private static User createUser(long id) {
User user = new User();
user.setId(id);
return user;
}
}
在上述代码中,我创建了四个User对象,其中两个使用@Qualifier标记,
然后使用@Autowired实现三种注入
第一个:使用普通@Autowired注入User对象到List中,此种方式会将所有的User对象都注入其中
第二个:使用@Autowired加@Qualifier注入User对象到List中,从输入结果可以看出来,这种方式将只带有
@Qualifier标记的User对象注入了进来,
第三个:通过指定Bean名称注入对象
至此可以看出来,通过Qualifier实现了Bean的逻辑分组。
下面将对@Qualifier进行扩展
@Qualifier扩展
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
String value() default "";
}
从源码可以看出@Qualifier 注解还可以作用于其他注解之上,以此实现扩展功能
自定义注解
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier
public @interface UserGroup {
}
使用自定义注解进行Bean的分组
public class QualifierAnnotationDependencyInjectionDemo {
@Autowired
@UserGroup
private List usersGroup;
public static void main(String[] args) {
AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();
applicationContext.register(QualifierAnnotationDependencyInjectionDemo.class);
applicationContext.refresh();
QualifierAnnotationDependencyInjectionDemo bean = applicationContext.getBean(QualifierAnnotationDependencyInjectionDemo.class);
System.out.println(bean.usersGroup);
// output: [User{id=5, name='null'}]
applicationContext.close();
}
@Bean
public User User1() {
return createUser(1L);
}
@Bean
@UserGroup
public User user5() {
return createUser(5L);
}
private static User createUser(long id) {
User user = new User();
user.setId(id);
return user;
}
}
通过上述代码输入可以看出,自定义注解同样也能实现Bean的分组
通过扩展@Qualifier注解可以实现一些自定义的其他功能。
SpringCloud中的@LoadBalance注解就是对@Qualifier注解的一种扩展,通过标记RestTemplate对象来实现额外的逻辑