大家都知道@Autowire等同于@Resource,都是Spring支持的注解方式动态装配bean。
区别 | @Autowire | @Resource |
---|---|---|
来源 | Spring注解 | JDK注解(JSR-250标准注解,属于J2EE) |
装配方式 | 优先按类型 | 优先按名称 |
属性 | required | name、type |
作用范围 | 字段、setter方法、构造器 | 字段、setter方法 |
@Autowire默认按照类型(by-type)装配,默认情况下要求依赖对象必须存在。
- 如果允许依赖对象为null,需设置required属性为false,即
@Autowired(required = false)
private UserMapper userMapper;
// 按照名称(by-name)装配,需结合@Qualifier注解使用,即
@Autowired(required = false)
@Qualifier("userMapper")
private UserMapper userMapper;
public @interface Autowired {
boolean required() default true;
}
@Resource默认按照名称(by-name)装配,名称可以通过name属性指定。
- 如果没有指定name属性
1. 当注解在字段上时,默认取name=字段名称装配。
2. 当注解在setter方法上时,默认取name=属性名称装配。
- 当按照名称(by-name)装配未匹配时,按照类型(by-type)装配。
- 当显示指定name属性后,只能按照名称(by-name)装配
@Resoure装配顺序
- 如果同时指定name和type属性,则找到唯一匹配的bean装配,未找到则抛异常;
- 如果指定name属性,则按照名称(by-name)装配,未找到则抛异常;
- 如果指定type属性,则按照类型(by-type)装配,未找到或者找到多个则抛异常;
- 既未指定name属性,又未指定type属性,则按照名称(by-name)装配;如果未找到,则按照类型(by-type)装配。
public @interface Resource {
/**
* The JNDI name of the resource. For field annotations,
* the default is the field name. For method annotations,
* the default is the JavaBeans property name corresponding
* to the method. For class annotations, there is no default
* and this must be specified.
*/
String name() default "";
/**
* The Java type of the resource. For field annotations,
* the default is the type of the field. For method annotations,
* the default is the type of the JavaBeans property.
* For class annotations, there is no default and this must be
* specified.
*/
Class<?> type() default java.lang.Object.class;
}
总结:
@Resource 如果name没有匹配,则按类型查找。两次搜索,显然,速度就下降了许多。
要用@Autowired注入的时候要确保UserService只有一个实现类。当实现类存在多个的时候有冲突。比如 AccountService 有两个实现类,使用注解@Service 会有冲突的哦。
具体使用哪个主要还是看业务场景,默认推荐使用@Resource。
不足之处或有什么地方需要补充的,欢迎留言,一起交流。