Spring常用注解——@Autowired自动装配的作用和原理

news2024/11/18 9:47:06

一. 认识·@Autowired

当我们在Spring框架中配置Bean时,常见的有三种办法:①使用xml ②使用注解 ③使用javeconfig。由于第一种方法需要在application.xml配置文件中使用大量<bean>标签来进行注入,就衍生了注解,我们只要使用@Autowired对成员变量、方法和构造函数进行标注,就可以来完成自动装配的工作, 通过 @Autowired的使用还可以消除 set ,get方法,大大减少了代码量。

eg:[使用xml配置文件注入Bean]

[使用@Autowired注解注入Bean]

  @Autowired
    public IAccountDao dao;
    @Autowired
    public IAccountService service;

二. 用法·@Autowired

 @Autowired
    替换:autowire属性,自动装配(默认按照类型装配,通过set方法,且方法可以省略)
    位置:修饰属性,set方法
    语法:@Autowired (默认为true)

@Autowired(required=false):表示忽略当前要注入的bean,如果有直接注入,没有跳过,不会报错。

 @Autowired(required="true"):表示注入的时候,该bean必须存在,否则就会注入失败。
    注意:1.如果容器中没有一个可以与之匹配且required属性为true则会报异常 NoSuchBeanDefinitionException
         2.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配
         3.如果容器中有多个可以类型可以与之匹配,则自动切换为按照名称装配,如果名称也没有匹配,则报异常
            NoUniqueBeanDefinitionException

        4.@Autowired是根据类型进行自动装配的,如果需要按名称进行装配,则需要配合@Qualifier使用;

三.原理

看看源码:@Autowired 位于 org.springframework.beans.factory.annotation.Autowired包下,其实现原理就是调用了AutowiredAnnotationBeanPostProcessor类下的postProcessProperties()方法。

1.AutowiredAnnotationBeanPostProcessor是BeanPostProcesser的一个实现类它的主要功能就是对带注解的方法,set方法,和任意配置方法进行自动注入,这些注入的成员是通过注解来实现自动装配的。

在AutowiredAnnotationBeanPostProcessor类的构造方法中,我们可以看到,这些注解包括Spring的@Autowired和@Value注解,还支持JSR-330的@Inject注解(功能基本类似),这些注解都是基于AutowiredAnnotationBeanPostProcessor实现的。

 public AutowiredAnnotationBeanPostProcessor() {
        this.autowiredAnnotationTypes.add(Autowired.class);
        this.autowiredAnnotationTypes.add(Value.class);

        try {
            this.autowiredAnnotationTypes.add(ClassUtils.forName("javax.inject.Inject", AutowiredAnnotationBeanPostProcessor.class.getClassLoader()));
            this.logger.trace("JSR-330 'javax.inject.Inject' annotation found and supported for autowiring");
        } catch (ClassNotFoundException var2) {
        }

    }

 (Bean的生命周期:实例化,属性赋值,初始化,操作使用,销毁)

AutowiredAnnotationBeanPostProcessor方法的调用,完成了扫描并处理自动注入的构造方法,之后会返回来doCreateBean方法中,所以其调用逻辑主要集中在doCreateBean()方法中,调用applyMergedBeanDefinitionPostProcessors方法,完成扫描并且注入属性和方法。

doCreateBean()主要分为三个部分,第一个部分是在实例化 Bean 的时候在 createBeanInstance 方法中会调用 AutowiredAnnotationBeanPostProcessor 中的方法来获取需要自动注入的构造方法,第二部分是调用 AutowiredAnnotationBeanPostProcessor 的方法来完成对所有需要自动注入的属性和方法的解析和缓存,最后一部分就是在 populatedBean 方法中调用到 AutowiredAnnotationBeanPostProcessor 中的方法来完成需要自动注入属性的注入工作。

protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {
        BeanWrapper instanceWrapper = null;
        if (mbd.isSingleton()) {
            instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);
        }
        // 1.处理自动注入构造方法
        if (instanceWrapper == null) {
            instanceWrapper = this.createBeanInstance(beanName, mbd, args);
        }

        Object bean = instanceWrapper.getWrappedInstance();
        Class<?> beanType = instanceWrapper.getWrappedClass();
        if (beanType != NullBean.class) {
            mbd.resolvedTargetType = beanType;
        }

        synchronized(mbd.postProcessingLock) {
            if (!mbd.postProcessed) {
                try {
                    // 2.扫描注解并注入
                    this.applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
                } catch (Throwable var17) {
                    throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Post-processing of merged bean definition failed", var17);
                }

                mbd.postProcessed = true;
            }
        }
......
 private <T> T populateBean(ResultSet rs, T bean, PropertyDescriptor[] props, int[] columnToProperty) throws SQLException {
        for(int i = 1; i < columnToProperty.length; ++i) {
            if (columnToProperty[i] != -1) {
                PropertyDescriptor prop = props[columnToProperty[i]];
                Class<?> propType = prop.getPropertyType();
                Object value = null;
                if (propType != null) {
                    value = this.processColumn(rs, i, propType);
                    if (value == null && propType.isPrimitive()) {
                        value = primitiveDefaults.get(propType);
                    }
                }

                // 存入Bean
                this.callSetter(bean, prop, value);
            }
        }

        return bean;
    }

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/981.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Paper写作开头部分怎么具体分析?

Paper的组成部分包括了正文以及结尾&#xff0c;不过Paper整体印象很大程度上是由Paper开头段决定的。然而&#xff0c;写好Paper开头并不是一件不费吹灰之力的事。那么&#xff0c;Paper开头怎么写&#xff1f;接下来就让小编来给大家讲解几个写Paper开头的方法&#xff0c;希…

【python】之字典及其操作

个人主页&#xff1a;天寒雨落的博客_CSDN博客-C,CSDN竞赛,python领域博主 特别标注&#xff1a;仅为自己的学习记录笔记&#xff0c;方便复习和加深记忆&#xff0c;仅供借鉴参考&#xff01; 目录 前言 字典的创建 格式 字典名{key1:value1,key2:value2......} 字典名di…

大前端进阶:vue

目录 1.vue概述与前端知识体系 1.vue概述 2.前端三要素 2.前端发展史 1.三端统一 2.后端技术 3.了解前后分离的演变史 1.后端为主的MVC时代 2.基于AJAX带来的SPA时代 3.前端为主的MV*时代 4.Node JS带来的全栈时代 5.总结 4.第一个Vue程序 1.什么是MVVM 2.为什么…

每天一个小细节:UDP协议特点与报文结构

在上一期的《每天应该小细节》中&#xff0c;外面介绍了协议这个概念&#xff0c;那么在我们的传输层有两个非常重要的协议&#xff0c;那便是TCP/IP和UDP协议&#xff0c;那么今天就来详细介绍一下UDP协议的主要内容。 上期每天一个小细节指路&#x1f432;&#x1f432;&…

【马里奥数据结构吃“金币”】时间复杂度和空间复杂度

作者&#xff1a;一个喜欢猫咪的的程序员 专栏&#xff1a;《数据结构》 喜欢的话&#xff1a;世间因为少年的挺身而出&#xff0c;而更加瑰丽。 ——《人民日报》 目录 时间复杂度&#xff1a; 大O渐进表示法&#xff1a; 空间复杂度&#x…

文件操作学不会?快进来,带你深入理解->C语言文件操作

你将收获&#xff1a; 进一步理解缓冲区&#xff0c;以及引申出getchar(),scanf("%c",&c)接收数据时&#xff0c;易踩坑的地方&#xff0c;并对其解释。 w,r,a打开文件后如何正确使用读、写函数。 还有其它收获… 文件为什么存在什么是文件文件的唯一标识符缓冲文…

【FLASH存储器系列一】非易失性存储器基本原理之EPROM

1非易失性器件的存储原理 1.1最小存储单元-浮栅晶体管 我们当前使用的非易失性存储器的基本存储单元基本都是浮栅晶体管。技术在发展&#xff0c;浮栅晶体管的结构也在调整演进&#xff0c;接下来将用系列文章中的三篇分享EPROM、EEPROM、FLASH这三种非易失存储器件的基本存储…

麒麟系统开发笔记(九):在国产麒麟系统上搭建宇视摄像头SDK基础环境Demo

若该文为原创文章&#xff0c;转载请注明原文出处 本文章博客地址&#xff1a;https://hpzwl.blog.csdn.net/article/details/127532255 红胖子(红模仿)的博文大全&#xff1a;开发技术集合&#xff08;包含Qt实用技术、树莓派、三维、OpenCV、OpenGL、ffmpeg、OSG、单片机、软…

链路状态路由协议 OSPF (二)

作者简介&#xff1a;一名在校云计算网络运维学生、每天分享网络运维的学习经验、和学习笔记。 座右铭&#xff1a;低头赶路&#xff0c;敬事如仪 个人主页&#xff1a;网络豆的主页​​​​​​ 目录 前言 一.Router ID 1.什么是Router ID 2.获得Router ID方法 二.DR和…

每日一题(day9)

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录俩到经典题目一、走方格的方案数题目描述解题分析代码演示二.另类加法题目描述&#xff1a;解题分析常见的位运算代码演示总结俩到经典题目 一、走方格的方案数 题目…

【小嘟陪你刷题14】二叉树的最小深度、二叉树的所有路径、翻转二叉树

目录一、二叉树的最小深度思路一&#xff1a;深度优先搜索代码实现思路二&#xff1a;广度优先搜索代码实现二、二叉树的所有路径思路一&#xff1a;递归法代码实现思路二&#xff1a;迭代法三、翻转二叉树思路一&#xff1a;递归法代码实现思路二&#xff1a;迭代法代码实现一…

controller传输from-data数据格式的内容,取出传入数据为from-data格式的值

传输from-data数据格式的内容 postman里面的格式如下 接下来&#xff0c;便将上面的内容转换为代码 第一步&#xff1a;将File转为MultipartFile格式 首先&#xff0c;我们只能将File转为改格式才能进行网络传输&#xff0c;转换方式请看这篇博客&#xff1a;https://blog.…

推动行业数字化转型,亚马逊云科技自身就是“好把式”

&#xff08;亚马逊全球副总裁、亚马逊云科技大中华区执行董事张文翊&#xff09; 在2022年10月的亚马逊云科技中国峰会上&#xff0c;亚马逊云科技宣布了四大战略举措——“连中外、襄百业、携伙伴、促绿色“&#xff0c;进一步为中国本地客户赋能数字化探索与创新&#xff0…

顺序表实现—数据结构

文章目录一、顺序表概念及结构二、动态顺序表和静态顺序表的选择三、动态顺序表的实现逻辑&#xff08;1&#xff09;创建结构体&#xff08;2&#xff09;具体函数实现&#xff08;*&#xff09;顺序表初始化&#xff08;*&#xff09;释放顺序表&#xff08;*&#xff09;打印…

青少年python系列 21.turtle库绘制一个8

#绘制一个8import turtle#上方的小圆&#xff0c;圆心在左turtle.circle(80)#下方的大圆&#xff0c;圆心在右turtle.circle(-100)turtle.done() 青少年python教学视频ppt源码 青少年python系列目录_老程序员115的博客-CSDN博客 csdn文章推荐受影响解决办法10个字10行 csdn文…

梦开始的地方—— C语言指针入门

文章目录指针入门1.指针概念2. 指针和指针类型3. 野指针造成野指针的原因如何避免野指针4. 指针的运算指针加减整数指针的运算关系指针的关系运算5.指针和数组6. 二级指针7. 指针数组指针入门 1.指针概念 指针(Pointer) 是编程语言中的一个对象&#xff0c;利用地址&#xff…

31、Java——JDBC实现账号密码登录

✅作者简介&#xff1a;热爱国学的Java后端开发者&#xff0c;修心和技术同步精进。 &#x1f34e;个人主页&#xff1a;乐趣国学的博客 &#x1f34a;个人信条&#xff1a;不迁怒&#xff0c;不贰过。小知识&#xff0c;大智慧。 &#x1f49e;当前专栏&#xff1a;Java案例分…

Kong自动注册kong-spring-boot-stater

前言 kong-spring-boot-stater框架是为了解决SpringBoot项目和kong网关的自动注册&#xff0c;虽然Kong网关有提供可视化管理后台的操作界面&#xff0c;但是在多服务、多环境的时候在管理后台挨个配置每个服务节点是比较麻烦的&#xff0c;所以这也是kong-spring-boot-stater…

P3654 First Step (ファーストステップ)——暴力枚举

First Step (ファーストステップ) 题目背景 知らないことばかりなにもかもが&#xff08;どうしたらいいの&#xff1f;&#xff09; 一切的一切 尽是充满了未知数&#xff08;该如何是好&#xff09; それでも期待で足が軽いよ&#xff08;ジャンプだ&#xff01;&#xff09…

项目流程管理工具:OmniPlan Pro 4 中文

如何更好的管理项目流程&#xff1f;OmniPlan Pro 4中文是个很好的帮手&#xff0c;非常好用的项目流程管理工具&#xff0c; 强大的规划&#xff0c;管理复杂性&#xff1a; 引入三个新的内置模板&#xff1a;标准项目、标准项目&#xff08;样式&#xff09;和简单项目。 …