您当前的位置: 首页 > 

梁云亮

暂无认证

  • 3浏览

    0关注

    1211博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

@Autowired 与@Resource的区别

梁云亮 发布时间:2019-11-24 23:41:38 ,浏览量:3

概述 共同点

两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。两者大体使用相同。

不同点
  • @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired; 它按照byType注入。

  • @Autowired默认按类型装配(这个注解是属业spring的),默认情况下必须要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果我们想使用名称装配可以结合@Qualifier注解进行使用

  • @Autowired是根据类型进行自动装配的。如果当Spring上下文中存在不止一个UserDao类型的bean时,就会抛出BeanCreationException异常;如果Spring上下文中不存在UserDao类型的bean,也会抛出BeanCreationException异常。当然我们可以使用@Qualifier配合@Autowired来解决这些问题。@Qualifier一般作为@Autowired的修饰用。

  • @Resource(这个注解属于J2EE的,java自带的注解),默认按照名称进行装配,名称可以通过name属性进行指定,如果没有指定name属性,当注解写在字段上时,默认取字段名进行安装名称查找,如果注解写在setter方法上默认取属性名进行装配。当找不到与名称匹配的bean时才按照类型进行装配。但是需要注意的是,如果name属性一旦指定,就只会按照名称进行装配。

  • Spring属于第三方的,J2EE是Java自己的东西。使用@Resource可以减少代码和Spring之间的耦合,代码看起就比较优雅,而且实际工作中@Resource比@Autowired出的问题更少,推荐使用@Resource。

@Autowired
  • @Autowired为Spring提供的注解,需要导入包org.springframework.beans.factory.annotation.Autowired。
  • @Autowired采取的策略是按照类型注入。
  • 默认情况下,@Autowired要求依赖对象必须存在,如果要允许null值,可以设置它的required属性为false,如:@Autowired(required=false) ,如果想使用名称装配可以结合@Qualifier注解
    public class UserService {
        @Autowired
        private UserDao userDao; 
    }
    
    上面代码会去spring容器中找到类型为UserDao的类,然后将其注入进来。
  • 当一个类型有多个bean值的时候,会造成无法选择具体注入哪一个实例的情况,这个时候需要配合@Qualifier使用,@Qualifier告诉spring具体去装配哪个对象:
    public class UserService {
        @Autowired
        @Qualifier(name="userDao123")    
        private UserDao userDao; 
    }
    
    上面代码可以通过类型和名称定位到具体的对象。

@Autowired的注入逻辑:

  1. 找到所有类型符合的bean
  2. 如果没有类型符合的bean,则看@Autowired的required属性是否为true,是则抛出异常,否则返回null
  3. 如果只有一个,则将这个bean注入
  4. 如果有多个bean 4.1. 选择其中带有Primary注解的bean:此时,如果只有一个则直接注入;如果有多个bean都带有Primary注解则报错,如果不存在就下一步 4.2. 选择其中优先级最高的bean(优先级使用javax.annotation.Priority表明):如果只有一个则直接注入,如果有多个bean的优先级并列最高则报错,如果不存在就下一步 4.3 选择beanName和当前要注入的属性名相同的bean进行注入:有则注入,没有则报错
@Resource
  • @Resource注解由J2EE提供,需要导入包javax.annotation.Resource。
  • @Resource默认按照ByName自动注入。   @Resource有两个属性是比较重要,分是name和type:Spring将@Resource注解的name属性解析为bean的名字,将type属性则解析为bean的类型。所以如果使用name属性,则使用byName的自动注入策略,而使用type属性时则使用byType自动注入策略。
    • 如果既不指定name也不指定type属性,这时将通过反射机制使用byName自动注入策略。
    • 如果name属性一旦指定,@Resource就只会按照名称进行装配。
public class UserService {
    @Resource  
    private UserDao userDao; 
    
    @Resource(name="provinceDao")  
    private ProvinceDao provinceDao; 
    
    @Resource(type="SalesDao")  
    private SalesDao salesDao; 
    
    @Resource(name="goodsDao",type="GoodsDao")  
    private GoodsDao goodsDao; 
}    

@Resource装配顺序:

  1. 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常
  2. 如果指定了name,则从Spring上下文中查找name匹配的bean进行装配,找到将bean注入,找不到则抛出异常
  3. 如果指定了type,则从Spring上下文中找到类似匹配的唯一bean进行装配,找到将bean注入,找不到或是找到多个,都会抛出异常
  4. 如果没有指定name,则把属性名作为名字进行查找,找到将bean注入,当按照名字找不到时,按照类型进行查找
  5. 如果既没有指定name又没有指定type,则自动按照byName方式进行装配;如果没有匹配到,则回退为按照类型进行匹配,如果匹配则自动装配
总结:
  • 默认:@Autowired按byType自动注入,而@Resource默认按 byName自动注入
  • @Resource按照类型查找的逻辑和@Autowired是一样的
  • Spring属于第三方的,J2EE是Java自己的东西。
  • 使用@Resource可以减少代码和Spring之间的耦合。
  • 两者都可以写在字段和setter方法上。两者如果都写在字段上,那么就不需要再写setter方法。
关注
打赏
1665409997
查看更多评论
立即登录/注册

微信扫码登录

0.0400s