Spring @Autowire注解源码详解

news2024/12/25 10:10:16

目录

一:触发方式:

二:源码解析

2.1 扫描注入点

2.2 属性赋值


一:触发方式:

1.Spring容器在每个Bean实例化之后,调用AutowireAnnotationBeanPostProcessor的postProcessMergedBeanDefinition方法进行扫描注入点

2.Spring在每个Bean实例化之后,扫描完注入点之后,调用populateBean进行Bean注入,调用postProcessPropertyValues方法

二:源码解析

2.1 扫描注入点

通过在属性、构造方法、set方法上添加@Autowire注解可以将Bean进行依赖注入。

package service;

import org.springframework.beans.factory.annotation.Autowired;

public class UserService1 {

    @Autowired
    private  OrderService orderService;

    public void test(){
        System.out.println(orderService);
    }

}

首先先查找注入点,在创建Bean时,实例化后,调用

AbstractAutowireCapableBeanFactory.java

	protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args)
			throws BeanCreationException {

....

  if (!mbd.postProcessed) {
				try {
					//todo 在实例化后,对MergeBeanDefinition进行属性修改
					applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
				}
				catch (Throwable ex) {
					throw new BeanCreationException(mbd.getResourceDescription(), beanName,
							"Post-processing of merged bean definition failed", ex);
				}
				mbd.postProcessed = true;
			}

..

}

进入applyMergedBeanDefinitionPostProcessors方法中,调用processor.postProcessMergedBeanDefinition(mbd,beanType,beanName);

	protected void applyMergedBeanDefinitionPostProcessors(RootBeanDefinition mbd, Class<?> beanType, String beanName) {
		for (MergedBeanDefinitionPostProcessor processor : getBeanPostProcessorCache().mergedDefinition) {
			processor.postProcessMergedBeanDefinition(mbd, beanType, beanName);
		}
	}

处理@Autowire注解的类时AutowiredAnnotationBeanPostProcessor

 进入findAutowiringMetadata(beanName,beanType,null);

 

buildAutowiringMetadata(final Class<?> clazz) 方法中,循环遍历属性和循环遍历方法

,其中属性和方法不能是静态的 ,将field和required封装成一个AutowireFieldElement的一项,加入到currElements,最后合并成elements 

 

以上就是依赖注入寻找注入点的过程,还没进行属性赋值

2.2 属性赋值

在Bean的实例化之后,进行循环依赖、属性填充、初始化、销毁bean。

进入到 populateBean(beanName, mbd, instanceWrapper);

主要根据postProcessProperties 进行属性注入

在这里找注入点、属性赋值。查找注入点上面分析过,下面分析属性赋值。

 @Autowire注解加在field上的inject()方法在AutowiredFieldElement内部类中

 第一次没有缓存进入到resolveFieldValue(field,bean,beanName)中,缓存针对于原型bean,因为单例bean只会创建一次,属性也是注入一次。

最终在DefaultListableBeanFactory.java中 将bean找到返回

1.首先处理@Value注解

2.判断是不是Map、List复杂Bean,其中还是调用findAutowireCandidates方法,根据类型去Spring容器中去找

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, valueType,
      new MultiElementDescriptor(descriptor));

3.根据类型去Spring容器中找Bean,返回的key为beanName,value有可能是bean对象,有可能是bean class

Map<String, Object> matchingBeans = findAutowireCandidates(beanName, type, descriptor);

4.如果matcingbeans.size >1 根据类型找到多个bean时,再根据name去找,调用

determineAutowireCandidate 方法,先去判断有没有加@primary注解 ,如果有则返回这个bean,然后再判断这个bean的优先级,再匹配descriptor的名字,要么是字段的名字,要么是set方法入参的名字。最终返回这个beanName,如果这些注解都没有加则返回null。

5.如果第四步返回的bull,并且没有配置@Autowire(required=false) 并且 beans不是复杂类型,则抛异常  expected single matching bean but found beanName

6.根据beanName,获取bean /bean class 返回

 

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

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

相关文章

[附源码]计算机毕业设计美发店会员管理系统Springboot程序

项目运行 环境配置&#xff1a; Jdk1.8 Tomcat7.0 Mysql HBuilderX&#xff08;Webstorm也行&#xff09; Eclispe&#xff08;IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持&#xff09;。 项目技术&#xff1a; SSM mybatis Maven Vue 等等组成&#xff0c;B/S模式 M…

七周成为数据分析师 | 数据可视化

一.常见的初级图表 维度&#xff1a;描述分析的角度和属性&#xff0c;分类数据&#xff08;时间&#xff0c;地理位置&#xff0c;产品类型等&#xff09; 度量&#xff1a;具体的参考数值&#xff0c;数值数据&#xff08;元&#xff0c;销量&#xff0c;销售金额等&#x…

windows监控linux服务器资源grafana+prometheus+node_exporter

Windows环境监控Linux服务器资源grafanaprometheusnode_exporter 1.安装包下载 链接&#xff1a;https://pan.baidu.com/s/1xqdIYNtadt2tRSN-XlELUw 提取码&#xff1a;12342.安装grafana &#xff08;1&#xff09;将压缩包解压后&#xff0c;在bin文件目录下&#xff0c;点…

【Linux】shell命令以及运行原理和Linux权限详解

本期主题&#xff1a;Linux权限详解博客主页&#xff1a;小峰同学分享小编的在Linux中学习到的知识和遇到的问题小编的能力有限&#xff0c;出现错误希望大家不吝赐 目录 &#x1f341;1.shell命令以及运行结果 &#x1f341;2. Linux用户管理 &#x1f341;3. Linux权限管理 …

Python进阶学习之阅读代码

起因 在这个过程中&#xff0c;学习到了一些东西&#xff0c;同时整理了自己以前的一些收获&#xff0c;然后分享给大家&#xff0c;有不对的地方还望海涵、指正。 阅读代码有助于处理bug 阅读代码是一项更重要的技能&#xff0c;在大学编程语言的考试中也有相关的考察——代…

Paper reading:Fine-Grained Head Pose Estimation Without Keypoints (CVPR2018)

Paper reading&#xff1a;Fine-Grained Head Pose Estimation Without Keypoints &#xff08;CVPR2018&#xff09; 一、 背景 为什么要读这篇论文&#xff0c;因为LZ之前要做头部姿态估计&#xff0c;看到一些传统的方法&#xff0c;都是先进行人脸检测&#xff0c;然后再…

Java基于JSP旅游网站系统的设计于实现

我国的旅游事业目前正处于一个科学技术日新月异飞速向前发展的环境中。信息技术和通信技术以令人目不暇接的速度发展&#xff0c;尤其是互联网络的广泛流行&#xff0c;使得各种服务信息已近乎透明&#xff0c;且个性突出的游客们已不再满足于死板的标准化的旅游项目&#xff0…

JavaScript-T2

JavaScript-T2 前言 本次主要讲解的知识点是&#xff1a; JavaScript自定义函数 JavaScript系统函数 JavaScript 事件 JavaScript 的常用事件 JavaScript自定义函数 函数就是为了完成程序中的某些特定功能而进行专门定义的一段程序代码 函数包括自定义函数和系统函数 使用函数…

Akka 学习(二)第一个入门程序

目录一 sbt 介绍1.1 Sbt1.2 下载安装1.3 sbt的特点1.4 Idea 配置Sbt开发工具二 构建定义2.1 指定版本2.2 build.sbt 设置三 代码实现3.1 Java版本3.2 Scala版本3.3 对比一 sbt 介绍 1.1 Sbt sbt 是为 Scala 和 Java 项目构建的。它是93.6%的 Scala 开发人员的首选构建工具&am…

2000-2021年各省GDP包括名义GDP、实际GDP、GDP平减指数(以2000年为基期)

全国31省市GDP平减指数(2000-2021年)及计算步骤 1、时间&#xff1a;2000-2021年 2、范围&#xff1a;31省 3、数据包括&#xff1a;2000-2021年各省市GDP平减指数&#xff0c;以2000年为基期&#xff0c;包括数据来源、计算方法、公式等。 4、计算步骤&#xff1a; 第一步…

物联卡采购注意要点有哪些

在这个万物互联的时代&#xff0c;针对于企业设备联网的物联卡就显得格外重要了&#xff0c;而共享单车&#xff0c;移动支付&#xff0c;智慧城市&#xff0c;自动售卖机等企业采购物联卡会面临着各种问题&#xff0c;低价陷阱&#xff0c;流量虚假&#xff0c;管理混乱&#…

sealos issue #2157 debug 思路流程记录

sealos issues#2157 debug思路流程前言分析issue剖析源码解决方案总结前言 这个项目蛮有意思的&#xff0c;sealos 是以 kubernetes 为内核的云操作系统发行版。 boss上看到 -> 沟通 -> 解决某个issue直接offer -> 舒服 本文记录解决 issue 的思路 分析issue BUG…

Linux系统常用的工具

1.1 Vscode编辑器 从官网下载 ubuntu 版本&#xff0c;官网地址&#xff1a;https://code.visualstudio.com/。下载xxx.deb的包。 或者使用指令下载&#xff1a;wget https://az764295.vo.msecnd.net/stable/6261075646f055b99068d3688932416f2346dd3b/code_1.73.1-1667967334…

基于Intel Lake-UP3平台为半导体与集成电路测试设备提供优异计算性能

为什么半导体和IC测试设备需要升级&#xff1f; 随着众多新的高性能应用的需求不断增加&#xff0c;信迈旨在为半导体集成电路测试设备领域的客户提供更好的方案。半导体和集成电路&#xff08;IC&#xff09;测试设备设计用于在一台测试机上同时对不同线路的数百个集成电路…

How Can We Know What Language Models Know?

Abstract 最近的工作通过让语言模型&#xff08;LM&#xff09;填补诸如“奥巴马是一个职业”之类的提示的空白&#xff0c;提出了一个有趣的结果&#xff0c;以检查语言模型&#xff08;LM&#xff09;中包含的知识。这些提示通常是手动创建的&#xff0c;而且很可能不是最佳…

Linux进程通信之进程信号

一、信号的概念&#xff1a; 信号机制是Linux最基本的通讯机制&#xff0c;它可以用来向一个或者多个进程发送异步事件信息&#xff0c;传送少量信息。信号是一个软件中断&#xff0c;并且是一个“软中断”&#xff08;只是告诉有这样一个信号&#xff0c;但这个信号具体如何进…

Redis6入门到实战------思维导图+章节目录

Redis学习大纲 思维导图 思维导图 Redis6入门到实战------1、NoSQL数据库简介 地址&#xff1a; Redis6入门到实战------2、Redis6概述和安装 地址&#xff1a; Redis6入门到实战------3、常用五大数据类型 地址&#xff1a; Redis6入门到实战------4、Redis6配置文件详解…

Stack Overflow 临时禁用 ChatGPT 生成内容,网友:人类和AI快打起来!

如果有一天我们查询到的「知识」真假难辨&#xff0c;那这就太可怕了。 要问最近 AI 圈哪个模型最火爆&#xff0c;你不得不把 OpenAI 推出的 ChatGPT 排在前面。自从发布以来&#xff0c;这个对话模型可谓是出尽风头&#xff0c;很多人更是对其产生了一百个新玩法&#xff0c;…

Linux系统移植四:Petalinux使用本地sstate-cache加速构建根文件系统

根文件系统简介 根文件系统 rootfs 是Linux内核启动以后挂载(mount)的第一个文件系统&#xff0c;然后从根文件系统中读取初始化脚本&#xff0c;比如rcS&#xff0c;inittab等 根文件系统和Linux内核是分开的&#xff0c;单独的Linux内核是没法正常工作的&#xff0c;必须要…

TPM零知识学习六 —— tpm模拟器安装

本文参考以下链接&#xff1a; TPM模拟器和TPM2-TSS安装_jianming21的博客-CSDN博客_tpm2-tss 可信平台模块TPM&#xff08;Trusted Platform Module&#xff09;介绍及tpm-tools安装使用_jinhuazhe2013的博客-CSDN博客_tpm模块 1. 源码下载 运行以下命令下载源码&#xff1…