概述
在日常開發(fā)中經(jīng)常遇到會(huì)注冊(cè)多個(gè)相同類型的Bean到Spring容器中,在注入時(shí),通常會(huì)選取其中一個(gè)Bean來使用,使用@Autowired和@Qualifier注解可以解決這一問題,示例
@Autowired
@Qualifier("user1")
private User user;
上述代碼就是使用@Qualifier注解指明要注入哪個(gè)Bean
實(shí)現(xiàn)Bean邏輯分組
@Qualifier不僅能實(shí)現(xiàn)注入指定Bean,標(biāo)注在Bean上面還能實(shí)現(xiàn)Bean的邏輯分組,這樣在注入的時(shí)候可以根據(jù)分組獲取,如下:
實(shí)體類 User
public class User {
private Long id;
private String name;
// ...省略getter,setter和toString 方法
}
演示
public class QualifierAnnotationDependencyInjectionDemo {
@Autowired
private List<User> users;
@Autowired
@Qualifier
private List<User> 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;
}
}
在上述代碼中,我創(chuàng)建了四個(gè)User對(duì)象,其中兩個(gè)使用@Qualifier標(biāo)記,
然后使用@Autowired實(shí)現(xiàn)三種注入
第一個(gè):使用普通@Autowired注入U(xiǎn)ser對(duì)象到List中,此種方式會(huì)將所有的User對(duì)象都注入其中
第二個(gè):使用@Autowired加@Qualifier注入U(xiǎn)ser對(duì)象到List中,從輸入結(jié)果可以看出來,這種方式將只帶有
@Qualifier標(biāo)記的User對(duì)象注入了進(jìn)來,
第三個(gè):通過指定Bean名稱注入對(duì)象
至此可以看出來,通過Qualifier實(shí)現(xiàn)了Bean的邏輯分組。
下面將對(duì)@Qualifier進(jìn)行擴(kuò)展
@Qualifier擴(kuò)展
@Target({ElementType.FIELD, ElementType.METHOD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Qualifier {
String value() default "";
}
從源碼可以看出@Qualifier 注解還可以作用于其他注解之上,以此實(shí)現(xiàn)擴(kuò)展功能
自定義注解
@Target({ElementType.FIELD, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Qualifier
public @interface UserGroup {
}
使用自定義注解進(jìn)行Bean的分組
public class QualifierAnnotationDependencyInjectionDemo {
@Autowired
@UserGroup
private List<User> 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;
}
}
通過上述代碼輸入可以看出,自定義注解同樣也能實(shí)現(xiàn)Bean的分組
通過擴(kuò)展@Qualifier注解可以實(shí)現(xiàn)一些自定義的其他功能。
SpringCloud中的@LoadBalance注解就是對(duì)@Qualifier注解的一種擴(kuò)展,通過標(biāo)記RestTemplate對(duì)象來實(shí)現(xiàn)額外的邏輯