admin管理员组文章数量:1623789
- Autowired等注解
- Spring依赖注入之@Autowired、@Qualifier、@Primary、@Priority注解用法
- Spring依赖注入之@Autowired、@Qualifier、@Primary、@Priority注解原理(上)
- Spring依赖注入之@Autowired、@Qualifier、@Primary、@Priority注解原理(下)
- Value注解
- 依赖注入之@Value原理(整体流程)
- 依赖注入之@Value原理(获取value值)
- 依赖注入之@Value原理(placeholder解析)
- 依赖注入之@Value原理(SpEL表达式解析)
- Lookup注解
- Spring Boot依赖注入之Lookup注解
@Autowired注解可以声明一个bean依赖的其他bean,spring在创建bean时会将这些依赖的bean注入进来,涉及到的注解有@Autowired、@Value、@Qualifier、@Primary、@Priority,本节主要介绍@Autowired、@Qualifier、@Primary、@Priority这几个注解的用法
@Autowired注解如下
@Target({ElementType.CONSTRUCTOR, ElementType.METHOD, ElementType.PARAMETER, ElementType.FIELD, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Autowired {
boolean required() default true;
}
required字段表示是否必须注入。这个注解可以用在很多地方:构造器、方法、参数、属性、注解上。在使用上会涉及多个bean会怎么选择、如何指定autowire优先级等问题。下面就这些使用上的问题具体分析
1、用在属性上
这是一个最常用方式
a、对属性进行注入
@Component
public class Dependent {
}
@Component
public class Comp {
@Autowired
private Dependent dependent;
}
Spring启动后Comp这个bean的dependent属性就会被注入依赖。
b、设置required=false
required默认是true,当找不到这个bean时会抛出异常;required=false,当找不到这个bean,则忽略不处理。如下:
@Component
public class Comp {
@Autowired(required = false)
private Dependent dependent = new Dependent();
}
此时如果Spring不存在Dependent类型的bean,则为一个默认值,如果存在则会注入进来。
c、对数组、List、Set、Map属性进行注入
还可以对数组、List、Set、Map类型的属性注入依赖。如下:
public class Dependent {
}
@Configuration(proxyBeanMethods = false)
public class DepConfig {
@Bean
public Dependent d1() {
return new Dependent();
}
@Bean
public Dependent d2() {
return new Dependent();
}
}
@Component
public class Comp {
@Autowired
private Dependent[] dependentArr;
@Autowired
private List<Dependent> dependentList;
@Autowired
private Set<Dependent> dependentSet;
@Autowired
private Map<String, Dependent> dependentMap;
}
实际上是分为三种情况来处理的:Map、Collection子接口、数组,而对于Collection子接口、数组两种情况,实际是先获取Map再转成对应的类型的。这里的实现比较tricky,限制比较多
Map
Field的类型必须是参数化Map<String, xxx>,也就是必须是Map类型(不能是HashMap、也不能是原型Map),并且Map的key必须是String类型,Value可以是各种Bean的类型
Collection子接口
Field的类型必须是Collection子接口(不能是子类)。处理分成了两步:第一步获取上述Map,第二步通过TypeConverter将Map转成对应Collection子接口类型。默认情况下TypeConverter能处理Map到List、Map到Set的转换,因此Field是List、Set是可以的的;默认情况下TypeConverter不能处理Typeconverter到SortedSet的转换,因此会抛出类型转换异常,但可以通过扩展TypeConverter将Map转换成SortedSet。对于结果是List的,还会根据优先级进行排序
数组
Field的类型是数组的情况,处理也是分为两步:第一步获取上述Map,第二步通过TypeConverter将Map转成数组,然后根据优先级进行排序。
2、用在构造函数上
@Component
public class Comp {
private Dependent[] dependentArr;
private List<Dependent> dependentList;
private Set<Dependent> dependentSet;
private Map<String, Dependent> dependentMap;
@Autowired
public Comp(Dependent[] dependentArr, List<Dependent> dependentList, Set<Dependent> dependentSet, Map<String, Dependent> dependentMap) {
this.dependentArr = dependentArr;
this.dependentList = dependentList;
this.dependentSet = dependentSet;
this.dependentMap = dependentMap;
}
}
3、用在方法上
一般的用法是标注再setter上,但实际上对方法名没有限制、参数个数也没有限制、也不要求是public
@Component
public class Comp {
private Dependent[] dependentArr;
private List<Dependent> dependentList;
private Set<Dependent> dependentSet;
private Map<String, Dependent> dependentMap;
@Autowired
public void inject(Dependent[] dependentArr, List<Dependent> dependentList, Set<Dependent> dependentSet, Map<String, Dependent> dependentMap) {
this.dependentArr = dependentArr;
this.dependentList = dependentList;
this.dependentSet = dependentSet;
this.dependentMap = dependentMap;
}
}
4、用在参数上
@Autowired使用在方法参数上大部分情况下会忽略,只有两种情况会生效
- spring test
- 覆盖方法上的required参数
主要看第二种情况。方法或构造函数上的@Autowired里的required属性会对方法的所有参数生效,如果某些与其他参数不同的话,可以单独设置。并且为了这个方法/构造函数能够被识别到,某些情况下方法/构造函数上必须要有@Autowired注解(具体细节原理部分再分析)。如下
@Component
public class Comp {
private Dependent[] dependentArr;
private Dependent dependent;
@Autowired
public void inject(Dependent[] dependentArr,
@Autowired(required = false) @Qualifier("ddd") Dependent dependent) {
this.dependentArr = dependentArr;
this.dependent = dependent;
}
}
5、Optional和@Nullable
java1.8的Optional和@Nullable注解(任何Nullable注解,只要名字是Nullable,区分大小写)也可以用来达到和@Autowired的required=false一样的效果,可以用在field上、也可以用在方法参数上
@Component
public class Comp {
@Autowired
@Nullable
private Dependent[] dependentArr;
@Autowired
private Optional<Dependent> dependent;
}
@Component
public class Comp {
private Dependent[] dependentArr;
private Dependent dependent;
@Autowired
public void inject(@Nullable Dependent[] dependentArr,
Optional<Dependent> dependent) {
this.dependentArr = dependentArr;
dependent.ifPresent((dep) -> this.dependent = dep);
}
}
6、@Qualifier、@Primary、@Priority
当@Autowired只需要一个bean而存在多个同类型的bean,可以通过@Qualifier和@Primary注解来指定autowire哪一个,也可以通过@Priority指定优先级,Spring取优先级最高的(值最小的)
@Qualifier跟@Autowired一起使用,指定autowire的beanName
@Configuration(proxyBeanMethods = false)
public class DepConfig {
@Bean
public Dependent d1() {
return new Dependent();
}
@Bean
public Dependent d2() {
return new Dependent();
}
}
@Component
public class Comp {
@Autowired
@Qualifier("d1")
private Dependent dependent;
}
@Primary跟@Component或者@Bean一起使用,指定当存在多个类型的bean时,优先使用这一个(@Primary只能存在一个,有多个会抛出异常)
@Configuration(proxyBeanMethods = false)
public class DepConfig {
@Bean
public Dependent d1() {
return new Dependent();
}
@Bean
@Primary
public Dependent d2() {
return new Dependent();
}
}
@Component
public class Comp {
@Autowired
private Dependent dependent;
}
@Priority(javax.annotation.Priority)注解只能用在类上
@Target({TYPE,PARAMETER})
@Retention(RUNTIME)
@Documented
public @interface Priority {
int value();
}
bean定义
public class Dependent {
}
@Component
@Priority(2)
class DependentA extends Dependent {}
@Component
@Priority(0)
class DependentB extends Dependent {}
Comp将会注入DependentB这个bean
@Component
public class Comp {
@Autowired
private Dependent dependent;
}
7、bean排序
当注入的类型为数组或List时,会涉及排序问题,排序比前面的取最高优先级要复杂得多(前面只考虑@Priority注解),Spring的排序涉及到
- PriorityOrdered接口
- Ordered接口
- @Priority注解
- @Order注解
不同Bean进行比较时,规则如下:
- 实现了PriorityOrdered接口优先,都实现了PriorityOrdered接口或都没有实现该接口,再比较order
- order获取顺序为:PriorityOrdered#getOrder、Ordered#getOrder、@Order、@Priority
@Component
@Order(1)
class DependentA extends Dependent implements Ordered {
@Override
public int getOrder() {
return 3;
}
}
@Component
@Order(2)
@Priority(4)
class DependentB extends Dependent {}
@Component
public class Comp {
@Autowired
private Dependent[] dependent;
}
DependentA的order=3,DependentB的order=2,DependentB在前
本文标签: 注解AutoWiredSpringqualifierPriority
版权声明:本文标题:Spring依赖注入之@Autowired、@Qualifier、@Primary、@Priority注解用法 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/xitong/1728895401a1178342.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论