【Spring源码系列】Bean生命周期-实例化前

news2024/11/15 19:47:22

这里写目录标题

  • 前言
  • 一、实例化前 - InstantiationAwareBeanPostProcessor介绍
    • InstantiationAwareBeanPostProcessor实例化前作用
    • InstantiationAwareBeanPostProcessor实例化前代码案例
  • 二、实例化前 - 源码分析
    • 声明关键点
    • 源代码解读

前言

在Bean的生命周期中,‘实例化前’操作是借助InstantiationAwareBeanPostProcessor接口实现的。

一、实例化前 - InstantiationAwareBeanPostProcessor介绍

BeanPostProcessor 提供的两个方法是:初始化前初始化后
很多类实现BeanPostProcessor,且基于BeanPostProcessor类做了些扩展,比如InstantiationAwareBeanPostProcessor类,在此基础上扩展了实例化前实例化后

InstantiationAwareBeanPostProcessor实例化前作用

实例化前操作只做一件事情:遍历bean执行postProcessBeforeInstantiation方法

InstantiationAwareBeanPostProcessor实例化前代码案例

代码实现InstantiationAwareBeanPostProcessor接口:

@Component
public class UserBeanPostProcessor implements InstantiationAwareBeanPostProcessor {

	@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
		// 声明:如果不指定对哪个bean进行处理,默认是对All的bean都会处理。
		if ("userService".equals(beanName)) {
			System.out.println("实例化前");
		}
		return null;
	}

}

实现InstantiationAwareBeanPostProcessor接口关键点声明:
1、 必须被@Component注解修饰。保证实现InstantiationAwareBeanPostProcessor接口的类可以被Spring扫描,扫描之后会被记录到BeanPostProcessorCache-instantiationAware属性集合中,目的是在创建每个bean的时候都会遍历instantiationAware集合执行postProcessBeforeInstantiation方法。
2、实现InstantiationAwareBeanPostProcessor接口且重写postProcessBeforeInstantiation方法

二、实例化前 - 源码分析

声明关键点

在讲源码之前呢,我们可以先增强几个知识点的概念。这些知识点在阅读’Spring-实例化前‘ 源码中起着关键作用。

1、实例化前操作只做一件事情:遍历bean执行postProcessBeforeInstantiation方法
2、Spring规定每一个BeanDefinition会执行‘实例化前’方法
3、如果实例化前返回一个不为null的对象,下一步则直接到初始化后。postProcessBeforeInstantiation方法如果返回一个不为null的对象,表示不需要Spring来实例化了,并且后续的Spring依赖注入也不会进行了,会跳过一些步骤,直接执行初始化后这一步。
4、AbstractBeanFactory$BeanPostProcessorCache类的instantiationAware集合在‘初始化前’就已经有值。不仅仅是instantiationAware,其余三个集合在执行‘初始化前’都已经被赋值。

static class BeanPostProcessorCache {

		/**
		 * 下面四个均是BeanPostProcessor的子类;
		 *
		 */
		final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>();

		final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>();

		final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>();

		final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>();
	}

源代码解读

我们先找到Spring调用‘实例化前’的具体代码位置,‘实例化前’栈调用轨迹如下:
在这里插入图片描述org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[]):

// 实例化前
Object bean = resolveBeforeInstantiation(beanName, mbdToUse);

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation:

	@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			// synthetic表示合成,如果某些Bean式合成的,那么则不会经过BeanPostProcessor的处理
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					// 真正调用'实例化前'方法的地方。
					// 此处会获取postProcessBeforeInstantiation返回的对象,如果对象不为null则直接执行'初始化后'。
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInstantiation:

	@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		// getBeanPostProcessorCache()返回BeanPostProcessorCache对象,该对象的四个集合属性在执行'实例化前'就已经有值
		for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) {
			// 调用'实例化前-方法'
			Object result = bp.postProcessBeforeInstantiation(beanClass, beanName);
			if (result != null) {
				return result;
			}
		}
		return null;
	}

org.springframework.beans.factory.support.AbstractBeanFactory#getBeanPostProcessorCache:

BeanPostProcessorCache getBeanPostProcessorCache() {
		// '初始化前'调用之前,beanPostProcessorCache就已经有值
		BeanPostProcessorCache bpCache = this.beanPostProcessorCache;
		if (bpCache == null) {
			bpCache = new BeanPostProcessorCache();
			for (BeanPostProcessor bp : this.beanPostProcessors) {
				if (bp instanceof InstantiationAwareBeanPostProcessor) {
					bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp);
					if (bp instanceof SmartInstantiationAwareBeanPostProcessor) {
						bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp);
					}
				}
				if (bp instanceof DestructionAwareBeanPostProcessor) {
					bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp);
				}
				if (bp instanceof MergedBeanDefinitionPostProcessor) {
					bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp);
				}
			}
			this.beanPostProcessorCache = bpCache;
		}
		return bpCache;
	}

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

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

相关文章

Python还是很迷茫的小伙伴进来,教你用图秒懂Python

哈喽&#xff0c;大家好呀&#xff01;今天为大家带来12张图解python&#xff0c;让你们轻松学会了解python。 1.Python 解释器&#xff1a; Python数据结构&#xff1a;变量与运算符&#xff1a;Python 流程控制&#xff1a;Python 文件处理&#xff1a;python 输入输出&…

(三)Vue之模板语法

文章目录插值语法指令语法Vue学习目录上一篇&#xff1a;&#xff08;二&#xff09;初识Vue 下一篇&#xff1a;&#xff08;四&#xff09;Vue之数据绑定 Vue模板语法有2大类&#xff1a; 1.插值语法2.指令语法 插值语法 功能&#xff1a;用于解析标签体内容。 写法&…

lombok入门

目录 lombok概述 lombok安装 Getter、Setter ToString EqualsAndHashCode NotNull 生成构造方法相关注解 Data、Builder Log Cleanup、SneakyThrows lombok概述 以前的Java项目中&#xff0c;充斥着太多不友好的代码&#xff1a;POJO的getter/setter/toString/构造方…

Python迭代器和生成器

在Python中&#xff0c;很多对象都是可以通过for语句来直接遍历的&#xff0c;例如list、string、dict等等&#xff0c;这些对象都可以被称为可迭代对象。至于说哪些对象是可以被迭代访问的&#xff0c;就要了解一下迭代器相关的知识了。 迭代器 迭代器对象要求支持迭代器协议…

cpu设计和实现(总结篇)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 学习cpu&#xff0c;主要还是因为自己对它的原理和实现还有很多不明白、不清楚的地方&#xff0c;本着追根溯源的精神&#xff0c;正好借助于veril…

项目接入腾讯云短信服务SMS实现向用户发送手机验证码

1、自述 早在18年的时候&#xff0c;我就在项目中使用过阿里云的短信服务&#xff0c;现在我上阿里云短信控制台看&#xff0c;还能看到当时创建的短信签名&#xff0c;如下图所示。 出于某种原因&#xff0c;我现在想重新申请一个新的签名&#xff0c;却审批失败了&#xf…

HashMap和Hashtable的详细区别

HashMap和Hashtable的详细区别 一、简述&#xff1a; 1.安全性 Hashtable是线程安全&#xff0c;HashMap是非线程安全。HashMap的性能会高于Hashtable&#xff0c;我们平时使用时若无特殊需求建议使用HashMap&#xff0c;在多线程环境下若使用HashMap需要使用Collections.sy…

MyBatisPlus的使用入门

一、简介 官网&#xff1a;http://mp.baomidou.com/ 参考教程&#xff1a;http://mp.baomidou.com/guide/ MyBatis-Plus&#xff08;简称 MP&#xff09;是一个 MyBatis 的增强工具&#xff0c;在 MyBatis 的基础上只做增强不做改变&#xff0c;为简化开发、提高效率而生。 二、…

(ICLR-2019)DARTS:可微分架构搜索

DARTS&#xff1a;可微分架构搜索 paper题目&#xff1a;DARTS: DIFFERENTIABLE ARCHITECTURE SEARCH paper是CMU发表在ICLR 2019的工作 paper链接&#xff1a;地址 ABSTRACT 本文通过以可微分的方式制定任务来解决架构搜索的可扩展性挑战。与传统的在离散的、不可微分的搜索空…

【Android App】实战项目之使用OpenCV人脸识别实现找人功能(附源码和演示 超详细)

需要全部代码请点赞关注收藏后评论区留言私信~~~ 人脸识别自古有之&#xff0c;每当官府要捉拿某人时&#xff0c;便在城墙贴出通缉告示并附上那人的肖像。只是该办法依赖人们的回忆与主观判断&#xff0c;指认结果多有出入&#xff0c;算不上什么先进。 如今利用监控摄像头结合…

E3--FPGA实现LVDS收发实例和原理2022-12-03

1.什么是LVDS 一个新东西来的时候&#xff0c;人们总是希望能够宏观的定性的认识它。一个问题是&#xff0c;手机上用的“软件”该如何定义呢&#xff1f;来自百度百科的定义是&#xff0c;软件是指一系列按照特定顺序组织的计算机数据和指令的集合&#xff0c;如果你是非专业…

【Android App】给App集成WebRTC实现视频发送和接受实战(附源码和演示 超详细)

需要源码请点赞关注收藏后评论区留言私信~~~ 一、引入WebRTC开源库 WebRTC开源库的集成步骤如下&#xff1a; &#xff08;1&#xff09;给App模块的build.gradle添加WebRTC的依赖库配置&#xff1b; &#xff08;2&#xff09;App得申请录音和相机权限&#xff0c;还得申请…

[附源码]计算机毕业设计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…

K-means聚类算法及Python代码实现

K-means聚类算法&#xff08;事先数据并没有类别之分&#xff01;所有的数据都是一样的&#xff09; 1、概述 K-means算法是集简单和经典于一身的基于距离的聚类算法 采用距离作为相似性的评价指标&#xff0c;即认为两个对象的距离越近&#xff0c;其相似度就越大。 该算法…

享元设计模式

一、享元模式 1、定义 享元模式&#xff08;Flyweight Pattern&#xff09;又称作轻量级模式&#xff0c;是指提供减少对象数量从而改善应用所需的对象结构的方式。其宗旨是共享细粒度的对象&#xff0c;将多个对同一对象的访问集中起来&#xff0c;不必为每个访问者都创建一个…

C++智能指针shared_ptr用法

目录shared_ptr功能介绍shared_ptr提供的接口shared_ptr初始化shared_ptr管理指针的构造和析构shared_ptr获取原始指针shared_ptr的线程安全shared_ptr应用之enable_shared_from_this写在前面的总结&#xff1a;一个shared_ptr对象管理一个指针&#xff08;new T&#xff0c;在…

TCP/IP五层协议栈(3)

1.网络层 1.1.IP协议 IP协议格式:报头数据 4位版本 :IP协议的版本号.当前只有两个取值,4和6(0100 0110).( 这里讨论IPv4 )4位首部长度 :IP报头和TCP类似,都是可变的,带有选项.8位TOS :只有4位有效,那四位TOS分别表示( 最小延时,最大吞吐量,最高可靠性,最小成本 )(同一时刻只能…

使用 Qt for Android 获取并利用手机传感器数据(下篇)使用C++实现功能

在上一篇&#xff0c;我们搭建了开发环境。本篇&#xff0c;使用C代码真正实现功能。我们使用UDP协议从手机上指定发送的目的地、端口。效果如下图&#xff0c;完整工程参考https://gitcode.net/coloreaglestdio/qtcpp_demo/-/tree/master/android/sensors2pc&#xff1a; 移动…

全志T3 ARM+Ethercat+Codesys工业控制器设计方案

目前codesys EtherCAT驱动 做运动控制很有优势。现在总线式运动控制基本都是这种配置。 Codesys 号称PLC界的安卓&#xff0c;国内造PLC的 基本都用Codesys内核了。 如&#xff1a;汇川 &#xff0c;合信&#xff0c; 和利时 &#xff0c;英威腾&#xff0c; 台达。 包…

原子范数初探:以到达角估计为例

到达方向&#xff08;Direction-of-arrival, DOA&#xff09;估计是指从形成传感器阵列的多个接收天线的输出中检索若干电磁波/源的方向信息的过程。DOA估计是阵列信号处理中的一个主要问题&#xff0c;在雷达、声纳、无线通信中有着广泛的应用。 基本数学模型 考虑KKK个窄带…