首页 > 技术文章 > @Autowired和@Resource注解的一个意外重要区别

xhy-shine 2019-04-17 17:21 原文

今天上午,因为公司要跟客户展示最近开发的项目,然后安排了我重新构建一个template项目,用来向客户展示参考。基于已开发好的代码,我在进行一些简化抽取的时候出现了一个有趣的问题

因为我们有一个spring security配置类时需要每个模块都使用,就是可能有些参数不同,现在我把他弄到一个公共的jar包,把之前类拷贝进去,然后把参数写活,结果出现了一些有意思的小问题,它源代码使用了@Resource注解,用来对一个不是返回bean的方法进行参数注入,父类有使用@Autowired注解

执行后发现执行顺序是:

  1、先执行父类的构造

  2、执行本类构造

  3、执行本类有@Resource注解的方法

  4、父类按顺序执行标有@Autowired的方法

  5、执行子类标有的@Autowired方法

  6、最后执行子类的重写方法

当时有点郁闷,郁闷的是@Resource注解标注的方法是在最下面,不仅比本类放在它上面的标有@Autowired方法的优先级高,还高于父类@Autowired的方法,反正这样的情况以前还真是从来没遇到过,一方面没怎么实际经历这种场景,另一方面我从来不用@Resouce注解

然后我试着在子类添加了一个方法加上了@PostConstructo注解,这个时候执行顺序和上面差不多,@PostConstructor标注的方法在上面第五条之后执行

然后我试着加上一个@Bean注解的方法,它的优先级还要低于@PostConstructor

最后把@Resouce注解改成了@Autowired,这个时候是先执行父类标有@Autowired的方法。得出一个结论,@Resource标注在方法上注入方法形参的时候,它会优先于父类及其本类所有标有@Autowired的注解先执行。代码这里就不贴了,有兴趣可以自己写写

最后结论

  在@Configuration的配置类中标有@Resource、@Autowired这些的方法(必须要标注在方法上的情况下),会自动触发执行,且@Resource注解优先级高于@Autowired及其@PostConstructor,@PostConstructor优先级最低

 如果想注入多个bean,@Autowired还可以按下面的方式用来注入多个,而@Resource只能标注在方法上面,且也只能在方法形参注入一个

  @Autowired
    public void testAutowiredAnon(AuthenticationManagerBuilder auth, @Autowired ApplicationContext ApplicationContext){
        System.out.println("=========@Autowired testAutowiredAnon");
    }

    @Resource
    public void testResourceAnon(AuthenticationManagerBuilder auth){
        System.out.println("=========@Resource testResourceAnon");
    }

 

顺便温习下两个注解其他的区别

  @Autowired默认byType匹配,默认情况下要求依赖的bean必须存在,如果依赖的bean可以没有,可以使用require=false,如果想byName匹配,需要配合@Qualifier注解指定其value值,value值就是beanName

  @Resource默认byName匹配,没指定的话,它认为beanName是字段名,当找不到的会按照byType进行匹配,如果指定了name或type属性,它就会根据你指定的去找,没找到,抛出异常,@Resource不能放在方法的形参上,属于java jdk自带的注解

  

  

 

推荐阅读