精通 Spring 源码 | InstantiationAwareBeanPostProcessor(1)

本文主要是介绍精通 Spring 源码 | InstantiationAwareBeanPostProcessor(1),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

一、简介

InstantiationAwareBeanPostProcessor 是 Spring 的一个扩展点,他是 BeanPostProcessor 的子类,扩展了 BeanPostProcessor ,而外提供了 3 个方法:

1、Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)
2、boolean postProcessAfterInstantiation(Object bean, String beanName)
3、PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)

二、源码分析

本篇我们来探究 postProcessBeforeInstantiation 这个方法的作用,这个方法会返回一个 Object 类型的对象,在源码里面,如果有一个类实现了 InstantiationAwareBeanPostProcessor 这个后置处理器,在 postProcessBeforeInstantiation 方法里面返回了一个对象,那么直接返回,后续只会实现 BeanPostProcessor 的 postProcessAfterInitialization 方法,否则,按照正常流程走。我们可以看看源码:

			Object bean = resolveBeforeInstantiation(beanName, mbdToUse);//如果bean不为空直接返回if (bean != null) {return bean;}
	@Nullableprotected 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.if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {Class<?> targetType = determineTargetType(beanName, mbd);if (targetType != null) {//1、调用 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);if (bean != null) {//2、调用 BeanPostProcessor 的 postProcessAfterInitialization 方法bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}}}mbd.beforeInstantiationResolved = (bean != null);}return bean;}

下面的方法里面实现的是 postProcessBeforeInstantiation 这个方法

bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
	@Nullableprotected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {//拿到实现了BeanPostProcessors的接口for (BeanPostProcessor bp : getBeanPostProcessors()) {if (bp instanceof InstantiationAwareBeanPostProcessor) {InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);if (result != null) {return result;}}}return null;}

默认情况上面的方法返回的是空,如果不为空, 调用 BeanPostProcessor 的 postProcessAfterInitialization 方法

if (bean != null) {
//2、调用 BeanPostProcessor 的 postProcessAfterInitialization 方法bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
}

之后便是直接返回得到 Bean

三、示例

源码比较复杂,可能文字无法表达清楚,下面通过具体代码演示结果

@ComponentScan("com.javahly.spring59")
@Configuration
public class Appconfig {
}
@Component
public class IndexService {}
@Component
public class OrderService {}
@Component
public class UserService {}
@Component
public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {@Overridepublic Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {if (beanName.endsWith("indexService"))return new UserService();return null;}
}
public class Test {public static void main(String[] args){AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();applicationContext.register(Appconfig.class);applicationContext.refresh();System.out.println("orderService:"+applicationContext.getBean("orderService"));System.out.println("userService:"+applicationContext.getBean("userService"));System.out.println("indexService:"+applicationContext.getBean("indexService"));System.out.println("indexService:"+applicationContext.getBean("indexService"));}
}

这里我们把三个对象使用 @Component 标注,依旧是说我们想把这三个对象注入容器,不出意外,我们在运行 main 方法的时候会打印出这三个对象,但是,我们自定义了一个 MyInstantiationAwareBeanPostProcessor 扩展了InstantiationAwareBeanPostProcessor,住了一个偷梁换柱,把原本需要放入容器的 indexService 换成了 userService,打印结果如下:

orderService:com.javahly.spring59.service.OrderService@d7b1517
userService:com.javahly.spring59.service.UserService@16c0663d
indexService:com.javahly.spring59.service.UserService@23223dd8
indexService:com.javahly.spring59.service.UserService@23223dd8

—— 完

ABOUT

公众号:【星尘Pro】
github:https://github.com/huangliangyun

推荐阅读
史上最全,最完美的 JAVA 技术体系思维导图总结,没有之一!
全站导航 | 文章汇总!

这篇关于精通 Spring 源码 | InstantiationAwareBeanPostProcessor(1)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/562556

相关文章

JAVA中安装多个JDK的方法

《JAVA中安装多个JDK的方法》文章介绍了在Windows系统上安装多个JDK版本的方法,包括下载、安装路径修改、环境变量配置(JAVA_HOME和Path),并说明如何通过调整JAVA_HOME在... 首先去oracle官网下载好两个版本不同的jdk(需要登录Oracle账号,没有可以免费注册)下载完

Spring StateMachine实现状态机使用示例详解

《SpringStateMachine实现状态机使用示例详解》本文介绍SpringStateMachine实现状态机的步骤,包括依赖导入、枚举定义、状态转移规则配置、上下文管理及服务调用示例,重点解... 目录什么是状态机使用示例什么是状态机状态机是计算机科学中的​​核心建模工具​​,用于描述对象在其生命

Spring Boot 结合 WxJava 实现文章上传微信公众号草稿箱与群发

《SpringBoot结合WxJava实现文章上传微信公众号草稿箱与群发》本文将详细介绍如何使用SpringBoot框架结合WxJava开发工具包,实现文章上传到微信公众号草稿箱以及群发功能,... 目录一、项目环境准备1.1 开发环境1.2 微信公众号准备二、Spring Boot 项目搭建2.1 创建

Java中Integer128陷阱

《Java中Integer128陷阱》本文主要介绍了Java中Integer与int的区别及装箱拆箱机制,重点指出-128至127范围内的Integer值会复用缓存对象,导致==比较结果为true,下... 目录一、Integer和int的联系1.1 Integer和int的区别1.2 Integer和in

SpringSecurity整合redission序列化问题小结(最新整理)

《SpringSecurity整合redission序列化问题小结(最新整理)》文章详解SpringSecurity整合Redisson时的序列化问题,指出需排除官方Jackson依赖,通过自定义反序... 目录1. 前言2. Redission配置2.1 RedissonProperties2.2 Red

IntelliJ IDEA2025创建SpringBoot项目的实现步骤

《IntelliJIDEA2025创建SpringBoot项目的实现步骤》本文主要介绍了IntelliJIDEA2025创建SpringBoot项目的实现步骤,文中通过示例代码介绍的非常详细,对大家... 目录一、创建 Spring Boot 项目1. 新建项目2. 基础配置3. 选择依赖4. 生成项目5.

JSONArray在Java中的应用操作实例

《JSONArray在Java中的应用操作实例》JSONArray是org.json库用于处理JSON数组的类,可将Java对象(Map/List)转换为JSON格式,提供增删改查等操作,适用于前后端... 目录1. jsONArray定义与功能1.1 JSONArray概念阐释1.1.1 什么是JSONA

Java JDK1.8 安装和环境配置教程详解

《JavaJDK1.8安装和环境配置教程详解》文章简要介绍了JDK1.8的安装流程,包括官网下载对应系统版本、安装时选择非系统盘路径、配置JAVA_HOME、CLASSPATH和Path环境变量,... 目录1.下载JDK2.安装JDK3.配置环境变量4.检验JDK官网下载地址:Java Downloads

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

SpringBoot结合Docker进行容器化处理指南

《SpringBoot结合Docker进行容器化处理指南》在当今快速发展的软件工程领域,SpringBoot和Docker已经成为现代Java开发者的必备工具,本文将深入讲解如何将一个SpringBo... 目录前言一、为什么选择 Spring Bootjavascript + docker1. 快速部署与