对于使用Spring环境开发的,@Autowired注解与@Resource注解我们经常使用,可他们两者有什么区别?
Spring中bean有三种装配机制:
1、在xml中显式配置;
2、在Java代码中显式配置;
3、隐式的bean发现机制和自动装配。(自动化的装配bean)
Spring的自动装配大致步骤
1、组件扫描,spring会自动发现应用上下文中所创建的bean;
2、自动装配,spring自动满足bean之间的依赖,也就是控制反转IOC/依赖注入DI;
自动装配bean
1、注解@Autowired
package org.springframework.beans.factory.annotation.Autowired;
@Autowired(required=false)
(1)由Spring提供,只按照类型byType注入。
(2)@Autowired加上@Qualifier可以根据byName的方式自动装配 注意@Qualifier不能单独使用。
例:
@Autowired
@Qualifier(value = "userDao2")
private UserDao userDao2 ;
(3)可以写在字段或setter方法上。
写在字段上,会使用 Autowired 的方式在容器中查找是否有该参数 ,自动注入。
使用了@Autowired可以不用编写set方法,前提是自动装配的属性在IOC(Spring)容器中存在,且名字符合相关规则。
例:
@Autowired
private UserDao userDao2 ;
如果注解写在setter方法上默认取属性名进行装配,这个方法如果有参数userDao,会使用 Autowired 的方式在容器中查找是否有该参数 ,自动注入。
例:
@Autowired
public void setUserDao(UserDao userDao){
this.userDao=userDao;
}
(4)默认情况下必须要求依赖对象必须存在required=true,如果要允许null 值,可以设置它的required属性为false。
例:
@Autowired(required=false)
private UserDao userDao2;
2、注解@Resource
package javax.annotation.Resource;
@Resource(name="userDao2", type="UserDao")
它有两个重要的属性:name和type ,
Spring将@Resource的name属性(xml中bean的ID)解析为bean的名字,type属性则解析为bean的类型。
(1)由J2EE提供,默认按照名称byName自动注入,不成功则按byType的方式自动装配。
(2)如果既设置name属性也设置type属性,则使用byName自动注入策略。
(3)如果只设置name属性,则使用byName自动注入策略。
(4)如果只设置type属性,则使用byType自动注入策略。
(5)如果既不设置name属性也不设置type属性,则通过反射机制使用默认名称name进行byName自动注入策略。
(6)可以写在字段或setter方法上。
(7)如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但name属性一旦指定,就只会按照名称进行装配。
使用在字段上
例如:
@Resource
private UserDao userDao;
@Resource(name= userDao")
private UserDao userDao ;
@Resource(type="userDao")
private UserDao userDao ;
@Resource(name="userDao",type="UserDao")
private UserDao userDao
使用在方法上
@Resource(name="userDao")
public void setUserDao (UserDao userDao){
this.userDao=userDao;
}
@Resource装配顺序
(1)通过类型byType自动装配前提:同一类型的对象,在spring容器中唯一,如果不唯一会报不唯一的异常 NoUniqueBeanDefinitionException
(2)注解@Resource如有指定的name属性,先按属性name进行byName方式查找装配;
(3)其次再进行默认名称name的byName方式进行装配;
(4)前面两种如果都不成功,则按byType的方式自动装配。
(5)如果都不成功,则报异常。
3、功能对比
1、对于@Autowired有的功能@Resource都有,是对@Autowired的增强。
对于@Autowired只能按byType自动注入(@Autowired和注解Qualifier和使用也可以按byName自动注入)。
而@Resource可以按byType和byName两种自动注入策略。
2、两者都可以写在字段或setter方法上。
4、两个怎么选?
(1)按照类型byType进行装配 ,使用@Autowired和@Resource两个都可以,一般使用@Autowired。
(2)按照名称byName进行装配,使用@Resource比较简单。使用@Autowired按照类型byType进行装配 ,虽然可以配合@Qualifier按照类型byName注入,但多写一个注解。
(3)在字段上使用注解装配,推荐使用@Resource,这样就不用写setter方法了。
@Resource并且这个注解是属于J2EE的。