Spring Bean的初始化过程 initializeBean

news2024/11/25 18:29:59

目录

1.定义对象

2.注册对象

3.DEBUG Aware处理

4.完整初始化流程概览

5. applyBeanPostProcessorsBeforeInitialization

5.1 this.beanPostProcessors 里面的处理顺序

5.1.1 ApplicationContextAwareProcessor

5.1.2 ApplicationListenerDetector

5.1.3 WebApplicationContextServletContextAwareProcessor

5.1.4 ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

5.1.5 BeanPostProcessorChecker

5.1.6 ConfigurationPropertiesBindingPostProcessor

5.1.7 CommonAnnotationBeanPostProcessor

5.1.8  AutowiredAnnotationBeanPostProcessor

5.1.9  AnnotationAwareAspectJAutoProxyCreator

5.1.10  DataSourceInitializerPostProcessor

5.1.11 MethodValidationPostProcessor

5.1.12  PersistenceExceptionTranslationPostProcessor

5.1.13 KafkaListenerAnnotationBeanPostProcessor

 6. invokeInitMethods

7.  applyBeanPostProcessorsAfterInitialization

7.1  ApplicationListenerDetector

7.2 BeanPostProcessorChecker

7.3  AnnotationAwareAspectJAutoProxyCreator

7.4  DataSourceInitializerPostProcessor

7.5 org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor

7.6 KafkaListenerAnnotationBeanPostProcessor


1.定义对象

public class Apple implements InitializingBean, BeanPostProcessor, BeanNameAware, BeanClassLoaderAware, BeanFactoryAware {

    @PostConstruct
    public void postConstruct(){
        System.out.println(" construct之后 进行... ");
    }

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(" 【before】 initialization....... ");
        return BeanPostProcessor.super.postProcessBeforeInitialization(bean, beanName);
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println(" 【after】 initialization........ ");
        return BeanPostProcessor.super.postProcessAfterInitialization(bean, beanName);
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println(" 属性配置完成之后 进行了什么操作... ");
    }


    @Override
    public void setBeanClassLoader(ClassLoader classLoader) {
        System.out.println(classLoader);
    }

    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
        System.out.println(beanFactory);
    }

    @Override
    public void setBeanName(String name) {
        System.out.println(name);
    }
}

上面是对象。

2.注册对象

@Configuration
@Import(Apple.class)
public class Config {
}

或者用@Bean方式注册Apple对象,效果都是一样的。

3.DEBUG Aware处理

之后进入到

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeAwareMethods 

 由这个顺序也知道,

BeanNameAware -> BeanClassLoaderAware -> BeanFactoryAware

 aware也是spring用来进行各种初始化的接口。通过aware接口,我们可以在Spring容器未完全初始化的时候,进行各种配置,拿到Spring容器的工具进行使用。

4.完整初始化流程概览

执行顺序 

invokeAwareMethods -> applyBeanPostProcessorsBeforeInitialization ->
invokeInitMethods -> applyBeanPostProcessorsAfterInitialization

刚才已经看了 invokeAwareMethods;

接下来继续往下看

5. applyBeanPostProcessorsBeforeInitialization

 这好像没什么区别,都是调用 postProcessBeforeInitialization 方法。

点击 getBeanPostProcessors() 进入到父类方法里了

里面的具体内容: 




由这里也可以看出,根据环境不同,这里的类会不同,顺序也会不同。
暂时按图2顺序,进行bean的前置处理分析。

 

 

5.1 this.beanPostProcessors 里面的处理顺序

5.1.1 ApplicationContextAwareProcessor

 从上图也可以看到,如果当前类,没有实现这些接口,就会直接返回。

那如果是这个接口会做些什么呢?

由图可知,当我们实现了这些接口,会调用所属接口的对应方法。

同一个类实现多个接口,会多次调用。

@Component
public class AppleContextAware implements EnvironmentAware, ApplicationEventPublisherAware {
    @Override
    public void setApplicationEventPublisher(ApplicationEventPublisher applicationEventPublisher) {
        System.out.println("事件发布类已经调用成功="+applicationEventPublisher);
    }

    @Override
    public void setEnvironment(Environment environment) {
        System.out.println("获取到当前Spring的 environment=" + environment);
    }
}

 可以看到,是按照  invokeAwareInterfaces 里的执行顺序进行操作的。

第一个,可以让我们实现多个aware。

这与 3.DEBUG Aware处理 的aware相比,就是所有的类都会经过 3.DEBUG Aware处理

但是如果是 自己定义了 RootBeanDefinition  且  isSynthetic 为true 就不会走入这个方法。

 RootBeanDefinition在AbstractBeanDefinition的基础上定义了更多属性,初始化Bean需要的信息基本完善。具体内容可以自行搜寻,这里不是重点。

5.1.2 ApplicationListenerDetector

无操作。

5.1.3 WebApplicationContextServletContextAwareProcessor

 org.springframework.boot.web.servlet.context.WebApplicationContextServletContextAwareProcessor

当前处理器,没有实现自己的前置处理,而是复用了父类的前置处理。

从内容也可以看出来,是获取servlet上下文与配置。

5.1.4 ConfigurationClassPostProcessor.ImportAwareBeanPostProcessor

ImportAwareBeanPostProcessor 是 ConfigurationClassPostProcessor 的静态内部类。

 

 所以为了进一步了解这里到底怎么操作的。需要进一步查看  getImportingClassFor

 org.springframework.context.annotation.ConfigurationClassParser.ImportStack

 方法里面太绕了,总之是进入到了doConfiguration的操作。

当前类只要有@Import注解,且实现了ImportAware,就会拿出来进行操作。

(这部分找了一个多小时,都没找着头绪,我放弃了。先看别的,打好基础先。)

5.1.5 BeanPostProcessorChecker

org.springframework.context.support.PostProcessorRegistrationDelegate.BeanPostProcessorChecker

 这个没做操作

5.1.6 ConfigurationPropertiesBindingPostProcessor

对这个的应用:

@Data
@Configuration
@ConfigurationProperties(prefix = "apple")
public class AppleProperties {

    private String name;

    private int price;

}

 yml配置:

apple:
  name: 山东红富士 red
  price: 188

5.1.7 CommonAnnotationBeanPostProcessor

org.springframework.context.annotation.CommonAnnotationBeanPostProcessor

CommonAnnotationBeanPostProcessor  通过继承InitDestroyAnnotationBeanPostProcessor @javax.annotation.PostConstruct @javax.annotation.PreDestroy 注解的支持。以及依据bean name依赖注入的@javax.annotation.Resource 支持。也支持WebServiceRef 注解,具有创建JAX-WS服务端点的能力。最后,处理器还支持EJB3(@EJB)

注意:

@Resource的方法会直接被调用。

一般是用于调用setter方法进行赋值。

上面的这个两个方法,具体调用了 CommonAnnotationBeanPostProcessor 的父类InitDestroyAnnotationBeanPostProcessor。

在InitDestroyAnnotationBeanPostProcessor中分三个阶段完成这两个注解功能,分别为:

  1. 实现了MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()方法缓存初始化后和销毁前执行的方法。
  2. 实现了BeanPostProcessor.postProcessBeforeInitialization()用来执行@PostConstruct标注的方法。
  3. 实现了DestructionAwareBeanPostProcessor.postProcessBeforeDestruction()用来执行@PreDestroy标注的方法。

【下列方法是在  AbstractAutowireCapableBeanFactory 内】

AbstractAutowireCapableBeanFactory 在初始化bean之前,会对bean进行一个扫描。Autowired 和 Postconstruct 等等之类的,然后才是初始化。

 CommonAnnotationBeanPostProcessor  的  postProcessMergedBeanDefinition 首先调用了父类方法,支持了Init和Destory方法。

findResourceMetadata 里,支持了对@Resource以及WebService、Ejb的支持。

这个注入是在populateBean时进行注入的。

在初始化时,只会调用@PostConstruct注解的方法。

5.1.8  AutowiredAnnotationBeanPostProcessor

org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor

 默认父类方法,无操作。

5.1.9  AnnotationAwareAspectJAutoProxyCreator

org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator

默认父类方法,无操作。

5.1.10  DataSourceInitializerPostProcessor

 org.springframework.boot.autoconfigure.jdbc.DataSourceInitializerPostProcessor

默认实现,无操作。 

5.1.11 MethodValidationPostProcessor

org.springframework.validation.beanvalidation.MethodValidationPostProcessor

 默认实现,无操作。 

5.1.12  PersistenceExceptionTranslationPostProcessor

org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor

  默认实现,无操作。 

5.1.13 KafkaListenerAnnotationBeanPostProcessor

org.springframework.kafka.annotation.KafkaListenerAnnotationBeanPostProcessor

默认实现,无操作。

 6. invokeInitMethods

在这里主要是执行 InitializingBean 的实现类的 afterPropertiesSet 方法

org.springframework.beans.factory.InitializingBean

 

 

7.  applyBeanPostProcessorsAfterInitialization

 

和前置处理一样,都是一样的处理器。

只显示做了事情的PostProcessor.

7.1  ApplicationListenerDetector

ApplicationListenerDetector 就是为了进行注册监听器。

7.2 BeanPostProcessorChecker

BeanPostProcessorChecker检查xxx不适合所有的BeanPostProcessor来处理。即,存在出现“自动注入”不合适或无效的信息。


BeanPostProcessor是Spring的Bean工厂中的钩子(Hook),允许Spring框架在新创建Bean实例时对其进行定制化修改。它本身也是一个Bean,在通常情况下,其实例化顺序要优先于普通的Bean。因为有时BeanPostProcessor也会依赖一些Bean,所以,会存在一些普通Bean的实例化早于BeanPostProcessor的情况,因此就会造成一些问题。

7.3  AnnotationAwareAspectJAutoProxyCreator

在父类  AbstractAutoProxyCreator 里定义的

 进行AOP注册操作,具体实现过于复杂,将会开另外一篇文章进行探讨。

7.4  DataSourceInitializerPostProcessor

看别的文章,说是从beanFactory 是懒加载  DataSourceInitializerInvoker,从而对 dataSource进行处理。

7.5 org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor

在父类 AbstractAdvisingBeanPostProcessor 的默认方法。

可以看出来又是AOP相关内容。这些具体操作就得AOP相关内容进行分解。

7.6 KafkaListenerAnnotationBeanPostProcessor

对Kafka的一些操作,检查方法之类的。

 

OK。内容结束。

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

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

相关文章

水泥路面、桥梁基建、隧道裂痕裂缝检测数据集

在我之前的博文中已经写过几篇关于特定场景下的裂痕裂缝检测的模型实践文章,后面也有很项目应用都是基于此构建的,这里主要是对前面几篇博文的数据集进行介绍。 相应的系列文章如下,感兴趣的话可以自行移步阅读即可。 《基于yolov5sbifpn实…

Java基于springboot球员转会管理系统 +vue+elementUI

项目介绍 本球员转会管理系统是针对目前球员转会管理的实际需求,从实际工作出发,对过去的球员转会管理系统存在的问题进行分析,完善用户的使用体会。采用计算机系统来管理信息,取代人工管理模式,查询便利,信…

高精度加减乘除——C++实现

每日一句:每天早上醒来时,我们有两个简单的选择:回头去睡,继续做梦。或者起身去追逐梦想。 高精度加减乘除前言一、高精度加法1.基本思路2.分步讲解2.1输入字符数字2.2把字符数字转换为数字2.3实现add函数3.完整代码二、高精度减法…

[附源码]Python计算机毕业设计大学生网络安全题库系统Django(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程 项目运行 环境配置: Pychram社区版 python3.7.7 Mysql5.7 HBuilderXlist pipNavicat11Djangonodejs。 项目技术: django python Vue 等等组成,B/S模式 pychram管理等…

Linux进程通信

写在前面 今天主要的任务就是知道什么是进程通信?进程通信是如何实现的?前面我们学习了基础IO,再往前看又学习进程的相关的概念,那么今天我们通过进程的通信来把他们用起来.这个话题挺重要的,但是没有前面的大. 进程通信 "通信"这个单词很好理解,就是两个或者多…

Codon

又搬来了一个框架 并没用过啊 说着比c还厉害~ 大伙谁 研究过呢? 希望不是和咱们的中药一样~~ 众所周知,Python 是一门简单易学、具有强大功能的编程语言,在各种用户使用统计榜单中总是名列前茅。相应地,围绕 Python,研究者开发了…

Vector-常用CAN工具 - CANoe入门到精通_05

CAPL Test Module 在“Vector-常用CAN工具 - CANoe入门到精通”的第4/4篇中介绍了作为Server端的Network Node节点以及相应的一些常用函数,今天我们来介绍下当前依然有很多人在用的自动化脚本开发编译器 - CAPL Test Module,这个基本能满足单个功能模块…

KingbaseES V8R6备份恢复案例之---sys_waldump解析wal日志PITR恢复

​案例说明: 复现用户删除表(drop table)误操作,通过wal日志解析找到误操作时间点,执行基于时间点的恢复(PITR)。适用版本: KingbaseES V8R6 一、模拟业务现场操作 1、查看当前对象信息 prod# \dList of relationsSchema | …

R语言逻辑回归预测分析付费用户

对于某企业新用户,会利用大数据来分析该用户的信息来确定是否为付费用户,弄清楚用户属性,从而针对性的进行营销,提高运营人员的办事效率。 相关视频:R语言逻辑回归(Logistic回归)模型分类预测病…

javaScript内存管理及监控

1.1 内存定义 内存由可读写单元组成,表示一片可操作空间,开发者主动申请空间、使用空间、释放空间。内存主要存储变量等数据,局部变量当程序执行结束,且没有引用的时候就会随着消失,全局对象会始终存活到程序运行结束。…

【简单项目实战】用C++实现学生成绩管理系统

目录 ●功能介绍 ●案例 ●代码展示 ●结果展示 ●功能介绍 用 C设计一个程序,能提供下列功能: 1. 录入学生成绩信息。按照学号,姓名,语文,数学,英语的格式录入学生的成绩。 2.展示目前录入学生的成绩信息。以…

MeterSphere使用mock基础

目录 一、添加mock数据 1、进入页面添加 2、 添加单个mock 3、添加多个mock数据 二、运行mock 1、选择设置接口的TEST 2、选择mock环境 3、设置定义的mock参数运行 一、添加mock数据 1、进入页面添加 在接口定义页面,按下图1-2-3顺序添加 2、 添加单个mock…

[附源码]Nodejs计算机毕业设计基于JAVA人事管理系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置: Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术: Express框架 Node.js Vue 等等组成,B/S模式 Vscode管理前后端分…

如何利用TL431设计一个可调电压源

TL431是一个三脚电压可控的稳压器件,常用的封装有TO-92,SOT-23,SOT-89,电路符号是这个, TL431常被用在参考电压/基准电压电路,用来替代稳压管 其中1脚是reference,2脚是Anode,3脚是Cathode TL4…

基于微信小程序的校园二手交易-计算机毕业设计

项目介绍 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,校园二手交易被用户普遍使用,为方便用户能…

最新版网络组件包:Rebex Total Pack for .NET

Rebex Total Pack for .NET 组件包: Rebex 的所有 .NET 组件都在一个包中:SFTP、FTP、HTTPS、IMAP、POP3、SMTP、EWS、SNTP/Time/Daytime、Mail、MSG、TLS、SSH Shell、Telnet、终端仿真、安全、Syslog、WebSocket、 ZIP 压缩,SFTP/SSH 服务…

Java之final相关内容详解【面试题】

1、final关键字除了修饰类之外,还有哪些用法呢? (1)final修饰的变量,一旦赋值,不可重新赋值; (2) 如果引用为引用数据类型,比如对象、数组,则该对…

生成模型(二):VAE

自动编码器的发明是为了重建高维数据(这可能不是变异自动编码器的真实情况)。一个很好的副产品是降维:瓶颈层捕获了一个压缩的潜在编码。这样的低维表示可以作为各种应用中的嵌入向量(如搜索),帮助数据压缩…

计算机研究生就业方向之大厂销售(营销)

我一直跟学生们说你考计算机的研究生之前一定要想好你想干什么,如果你只是转码,那么你不一定要考研,至少以下几个职位研究生是没有啥优势的: 1,软件测试工程师(培训一下就行) 2,前…

世界杯---人生就是一届又一届世界杯

注意:下面有视频看到文章会有声音,如果打扰到您非常抱歉,视频在文章最下面,还望观众老爷们不要在意,蟹蟹理解~ 🚀write in front🚀 📝个人主页:认真写博客的夏目浅石. &a…