• @Autowired与@Resource区别


    文章目录


    一、前言

    @Autowired和@Resource都是用来自动装配bean的。

    • @Resource是JSR-250提供的,它是Java标准,绝大部分框架都支持。
    • @Autowired功能非常强大,但只适用于Spring框架,如果换成了JFinal等其他框架,功能就会失效。

    Spring Bean覆盖配置

    spring:
      main:
        allow-bean-definition-overriding: true
    
    • 1
    • 2
    • 3

    allow-bean-definition-overriding属性用于配置出现相同名称bean的情况如何处理:

    • 值为false时(默认值为false),如果出现相同名称的bean,直接抛异常。
    • 值为true时,表示支持相同名称的bean覆盖,后定义的bean会覆盖之前定义的相同名称的bean。

    下文会提到按类型装配,那么什么是同一类型呢?

    • 父类及其子类都属于父类这一类型
    • 接口及其实现类都属于接口这一类型

    二、@Autowired

    @Autowired是Spring提供的注解,用于自动装配。

    注解处理器

    AutowiredAnnotationBeanPostProcessor类是Autowired注解的注解处理器。

    关于注解处理器可参考文章:https://blog.csdn.net/JokerLJG/article/details/123548694

    装配方式

    • 按类型装配(默认使用的装配方式)。
    • 按名称装配(结合@Qualifier注解使用)。

    注解属性

    • required:默认值true。值为true时,表示必须注入,如bean不存在则会报错;值为false时,表示bean存在就注入,不存在则不注入。

    作用范围

    @Autowired的作用范围:成员变量、构造器、方法、参数、注解。

    1. 成员变量

    @Service
    public class UserService {
    
        @Autowired
        private IUser user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    使用最多的方式。

    2. 构造器

    @Service
    public class UserService {
    
        private IUser user;
    
        @Autowired
        public UserService(IUser user) {
            this.user = user;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    构造器上使用Autowired注解,实际上还是使用了成员变量装配的方式,并非构造器装配。

    3. 方法

    @Service
    public class UserService {
    
        @Autowired
        public void test(IUser user) {
           user.test();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    Spring会在项目启动的过程中,自动调用一次加了@Autowired注解的方法,我们可以在该方法做一些初始化的工作。

    4. 参数

    在构造器的入参上加Autowired注解

    @Service
    public class UserService {
    
        private IUser user;
    
        public UserService(@Autowired IUser user) {
            this.user = user;
            System.out.println("user:" + user);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    在非静态方法的入参上加Autowired注解

    @Service
    public class UserService {
    
        public void test(@Autowired IUser user) {
           user.test();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    5. 注解

    略。

    使用技巧

    同一类型多个bean

    当按类型装配时,如果该类型的bean不止一个时,会直接报错。举例说明:

    接口:

    public interface IUser {
        void test();
    }
    
    • 1
    • 2
    • 3

    实现类1:

    @Service
    public class User1 implements IUser{
        @Override
        public void test() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实现类2:

    @Service
    public class User2 implements IUser{
        @Override
        public void test() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    自动装配:

    @Service
    public class UserService {
    
        @Autowired
        private IUser user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    启动时的错误信息:

    Field userService in com.joker.controller.UserController required a single bean, but 2 were found:
    	- userServiceImpl1: defined in file [D:workmyspringboot	argetclassescomjokercontrollerUserServiceImpl1.class]
    	- userServiceImpl2: defined in file [D:workmyspringboot	argetclassescomjokercontrollerUserServiceImpl2.class]
    
    • 1
    • 2
    • 3

    @Primary的使用

    @Primary注解可以解决上述问题(按类型装配时,如果该类型的bean不止一个时,会报错)。

    当我们使用自动配置的方式装配Bean时,如果这个Bean有多个候选者,假如其中一个候选者具有@Primary注解修饰,该候选者会被选中,作为自动装配的bean。

    在上面代码不变的情况下,只需在User1或User2上加@Primary注解,此时@Autowired自动装配会成功,并且自动装配的是加了@Primary注解的这个类对应的bean。

    User1类加@Primary注解

    @Service
    @Primary
    public class User1 implements IUser{
        @Override
        public void test() {
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    @Qualifier的使用

    通过@Autowired和@Qualifier的结合使用可以按名称装配。

    @Service
    public class UserService {
    
        @Autowired
        @Qualifier("user1")
        private IUser user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    自动装配名称为user1的bean(注意:bean的类型也必须要满足为IUser类型)。

    装配多个实例

    我们一般使用的都是用@Autowired自动装配单个实例,但其实它也可以用来装配多个实例。可以通过List、Set、Map来装配多个实例,如下:

    @Service
    public class UserService {
    
        @Autowired
        private List userList;
    
        @Autowired
        private Set userSet;
    
        @Autowired
        private Map userMap;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    上面的装配方式会吧IUser类型的多个实例bean都装配的List、Set、Map中。

    @Autowired装配未生效

    下面列举常见@Autowired装配未生效的情况:

    1. @Autowired所在类未加@Controller、@Service、@Component、@Repository等注解,或者或者一些其它情况(如直接new对象的到实例)。这些情况会导致该类的bean并没有交给spring容器去管理,spring就无法完成自动装配的功能。

      public class UserService {
      
          @Autowired
          private IUser user;
      
          public void test() {
              user.say();
          }
      }
      
      • 1
      • 2
      • 3
      • 4
      • 5
      • 6
      • 7
      • 8
      • 9
    2. 注解未被@ComponentScan扫描到。

    三、@Resource

    @Resource是JDK自带的注解,用于自动装配。

    注解处理器

    CommonAnnotationBeanPostProcessor类是Resource的注解处理器。

    装配方式

    @Resource默认按照名称自动注入。

    • 既没指定name,也没指定type,自动按照名称装配(当注解写在字段上时,默认取字段名,当注解写在setter方法上时,默认取属性名进行装配。);如果没有匹配,则退而按照类型装配,找不到则抛出异常。

      如果没有指定 name 属性,

    • 如果指定了name,则从上下文中查找名称(id)匹配的bean进行装配,找不到则抛出异常。

    • 如果指定了type,则从上下文中找到类似匹配的唯一bean进行装配,找不到或是找到多个,都会抛出异常。

    • 如果同时指定了name和type,则从Spring上下文中找到唯一匹配的bean进行装配,找不到则抛出异常。

    注解属性

    Resource注解的主要属性:

    • name:指定需注入的bean的名称
    • type: 指定需注入的bean的类型

    作用范围

    @Resource的作用范围:类、成员变量、方法。

    1. 成员变量

    @Service
    public class UserService {
    
        @Resource
        private IUser user;
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    2. 方法

    @Service
    public class UserService {
    
        @Resource
        public void test(IUser user) {
            user.test();
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    3. 类

    略。

    四、@Autowired与@Resource对比

    二者对比

    @Autowired

    @Resource

    Spring定义的注解

    JSR-250定义的注解

    默认按类型自动装配

    默认按名称自动装配

    一个参数:required(默认true),表示是否必须注入

    七个参数:最重要的两个参数是name、type

    默认按类型自动装配
    如果要按名称自动装配,需要使用@Qualifier一起配合

    默认按名称自动装配
    如果指定了name,则按名称自动装配;如果指定了type,则按类型自动装配

    作用范围:构造器、方法、参数、成员变量、注解

    作用范围:类、成员变量、方法

    @Autowired装配流程

    请添加图片描述

    @Resource装配流程

    请添加图片描述

    先自我介绍一下,小编13年上师交大毕业,曾经在小公司待过,去过华为OPPO等大厂,18年进入阿里,直到现在。深知大多数初中级java工程师,想要升技能,往往是需要自己摸索成长或是报班学习,但对于培训机构动则近万元的学费,着实压力不小。自己不成体系的自学效率很低又漫长,而且容易碰到天花板技术停止不前。因此我收集了一份《java开发全套学习资料》送给大家,初衷也很简单,就是希望帮助到想自学又不知道该从何学起的朋友,同时减轻大家的负担。添加下方名片,即可获取全套学习资料哦

  • 相关阅读:
    OneForAll安装使用
    深度学习论文: Segment Any Anomaly without Training via Hybrid Prompt Regularization
    成都地区一汽大众汽车4s店营销策略研究
    ruoyi若依前端请求接口超时,增加响应时长
    精心整理170道Python面试题,建议收藏!
    智能漏电断路器主要有哪些功能?
    ARM编程环境搭建教程
    自动化平台切砖【Django】,持续推进。。。
    【MySQL】索引的作用及知识储备
    开始使用 ELEMENTOR
  • 原文地址:https://blog.csdn.net/m0_54853420/article/details/126055576