首先借个图,说明一下spring的bean的整个生命流程。

销毁什么的这个看图就知道怎么回事,使用的话一般都是纯业务,而且我们更关心spring是怎么初始化的,初始化成我们定义的那个样子。我们就是以这个出发点来看一下spring的大概流程。

spring的创建过程主要哪些步骤:

主要是对象的创建和对象的初始化

其实有人会疑问对象创建和对象初始化有什么区别?

其实就是先后次序的问题。
首先你要是用一个对象,要创建他,这里我们常见的是直接new一个。但是spring利用的是反射。
对象有时候不是创建好了,就可以用,尤其是spring,会出现要用到A对象,A对象以来别的B,C,D对象。毕竟你atowire的这些就是要用到的,你不希望拿到的这些都是null。所以初始化,就是让这个对象按照你设计的那样可以获得对应的值这些,可以去使用,很多程序都需要你自己初始化才能使用,或者说设计的人已经替你弄了一套默认的配置来让你使用。

创建解决的是有没有的问题,初始化决定的是能不能用的问题。否则仅是在内存中站一块空间,这是没啥作用的。

spring的初始化方式
一种是最早的配置文件的方式,里面会有一个 init-method,配置的是对应的这个类的初始化方法。这种初始化方式有一个缺点,初始化函数并不固定,由用户随意定义,这就需要 Spring 通过反射,在运行时动态地调用这个初始化函数。而反射又会影响代码执行的性能。(反射确实会影响性能,像做导入导出文件时,实际上有时候直接给一个确定的要比反射的模板类要快一些)

public class DemoClass {//...public void initDemo() {//...初始化..}
}// 配置:需要通过init-method显式地指定初始化方法
<bean id="demoBean" class="com.xzg.cd.DemoClass" init-method="initDemo"></bean>

另一种就是解决这个,Spring 提供了另外一个定义初始化函数的方法,那就是让类实现 Initializingbean 接口。

这个接口包含一个固定的初始化函数定义(afterPropertiesSet() 函数)。Spring 在初始化 Bean 的时候,可以直接通过 bean.afterPropertiesSet() 的方式,调用 Bean 对象上的这个函数,而不需要使用反射来调用了。


public class DemoClass implements InitializingBean{@Overridepublic void afterPropertiesSet() throws Exception {//...初始化...      }
}// 配置:不需要显式地指定初始化方法
<bean id="demoBean" class="com.xzg.cd.DemoClass"></bean>

spring初始化的细分

实际上分的更细一点,将初始化分为初始化前置操作、初始化、初始化后置操作这三个步骤。

前置操作和后置操作怎么回事,虽然从字面理解就能了解到他们的作用。一个是在初始化前要做的事,一个是初始化后的要做的事。但怎么实现,毕竟spring倡导的是“约定大于配置”。

中间的部分,初始化是在 InitializingBean里面。那他前后的操作在哪里。

同样也是一个接口BeanPostProcesso,里面postProcessBeforeInitialization和postProcessAfterInitialization看到名字就知道那个是前,那个是后。

我们只需要定义一个实现了 BeanPostProcessor 接口的处理器类,并在配置文件中像配置普通 Bean 一样去配置就可以了。Spring 中的 ApplicationContext 会自动检测在配置文件中实现了 BeanPostProcessor 接口的所有 Bean,并把它们注册到 BeanPostProcessor 处理器列表中。在 Spring 容器创建 Bean 的过程中,Spring 会逐一去调用这些处理器。

spring源码的相关初始化的部分
这里很多人还拿的是老的版本代码,一摸一样的文章转载来转载去的,而且还不严谨,我这里建议还是自己去代码里看具体的实现过程。

具体的部分位置是:AbstractAutowireCapableBeanFactory这个类,这个是我们自动装载bean的一个类


很多人看别人的文档直接支到doCreateBean方法,也不能说错,但我个人建议还是从她的公共入库public修饰的createBean开始一步一步的点,直到最后的实现方法doCreateBean方法。

    protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) throws BeanCreationException {BeanWrapper instanceWrapper = null;if (mbd.isSingleton()) {instanceWrapper = (BeanWrapper)this.factoryBeanInstanceCache.remove(beanName);}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 {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;}}boolean earlySingletonExposure = mbd.isSingleton() && this.allowCircularReferences && this.isSingletonCurrentlyInCreation(beanName);if (earlySingletonExposure) {if (this.logger.isTraceEnabled()) {this.logger.trace("Eagerly caching bean '" + beanName + "' to allow for resolving potential circular references");}this.addSingletonFactory(beanName, () -> {return this.getEarlyBeanReference(beanName, mbd, bean);});}Object exposedObject = bean;try {this.populateBean(beanName, mbd, instanceWrapper);exposedObject = this.initializeBean(beanName, exposedObject, mbd);} catch (Throwable var18) {if (var18 instanceof BeanCreationException && beanName.equals(((BeanCreationException)var18).getBeanName())) {throw (BeanCreationException)var18;}throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Initialization of bean failed", var18);}if (earlySingletonExposure) {Object earlySingletonReference = this.getSingleton(beanName, false);if (earlySingletonReference != null) {if (exposedObject == bean) {exposedObject = earlySingletonReference;} else if (!this.allowRawInjectionDespiteWrapping && this.hasDependentBean(beanName)) {String[] dependentBeans = this.getDependentBeans(beanName);Set<String> actualDependentBeans = new LinkedHashSet(dependentBeans.length);String[] var12 = dependentBeans;int var13 = dependentBeans.length;for(int var14 = 0; var14 < var13; ++var14) {String dependentBean = var12[var14];if (!this.removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {actualDependentBeans.add(dependentBean);}}if (!actualDependentBeans.isEmpty()) {throw new BeanCurrentlyInCreationException(beanName, "Bean with name '" + beanName + "' has been injected into other beans [" + StringUtils.collectionToCommaDelimitedString(actualDependentBeans) + "] in its raw version as part of a circular reference, but has eventually been wrapped. This means that said other beans do not use the final version of the bean. This is often the result of over-eager type matching - consider using 'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");}}}}try {this.registerDisposableBeanIfNecessary(beanName, bean, mbd);return exposedObject;} catch (BeanDefinitionValidationException var16) {throw new BeanCreationException(mbd.getResourceDescription(), beanName, "Invalid destruction signature", var16);}}

当然了,这个创建bean的方法外,里面还提供了销毁bean,处理bean的前置操作和bean的后置操作的公共方法。

spring源码学习:spring初始化流程相关推荐

  1. 从Spring源码探究IOC初始化流程

    随着不断地使用Spring,以及后续的Boot.cloud,不断的体会到这个拯救Java的生态体系的强大,也使我对于这个框架有了极大的好奇心,以至于产生了我为什么不能写一个这样的框架的思考. 通过自学 ...

  2. spring源码学习之路---深入AOP(终)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 上一章和各位一起看了一下sp ...

  3. 结合Spring源码学习单例设计模式

    之前我学习了 Spring Ioc,明白了 Spring IoC 容器是一个管理Bean的容器,在Spring的定义中,它要求所有的IoC容器都需要实现接口 BeanFactory ,它是一个顶级容器 ...

  4. 【Spring源码学习】Spring Bean的销毁

    [Spring源码学习]Spring Bean的销毁 一.注册bean销毁的类 1.registerDisposableBeanIfNecessary() 2.DisposableBeanAdapte ...

  5. spring源码学习之整合Mybatis原理分析

    本文主要解析spring是如何与mybatis进行整合,整合的过程中需要哪些组件的支持.以前面提到过的配置例子<spring源码学习之aop事物标签解析> 整合的过程中需要使用以下这个依赖 ...

  6. Spring源码学习(四) | @Configuration的cglib动态代理

    文章目录 前言 例子 @Configuration :full or lite 设置 full or lite Cglib生成代理类AppConfig Where is it generated Ho ...

  7. Spring源码学习的初步体会

    Spring源码学习的初步体会: 深入学习和巩固java的基础知识,其中的java知识范围全部,可以边研究源码边巩固复习基础知识 体会其中用到的设计思想:其中包含的设计原则和设计模式. 加深对spri ...

  8. Spring源码——动态AOP实现流程

    前言 最近回顾了一下Spring源码,准备用思维导图的方式简单的将整个源码内容的流程展示出来,思维导图.图片等文件更新在https://github.com/MrSorrow/spring-frame ...

  9. Spring源码——声明式事务流程

    前言 最近回顾了一下Spring源码,准备用思维导图的方式简单的将整个源码内容的流程展示出来,思维导图.图片等文件更新在https://github.com/MrSorrow/spring-frame ...

最新文章

  1. 计算机网络原理超详解说
  2. Bitmap Font 报错“characters from the file are not available in the font”解决办法
  3. 最新(2019/3)CSDN博客Markdown编辑格式说明,包含效果图
  4. 阿里云提示WordPress“/wp-includes/http.php输入IP验证不当”的解决办法
  5. 解决: Linux – git: command not found
  6. python wordpress xmlrpc_python-markdown自动发送wordpress文章(python-xmlrpc-wordpress)
  7. 多机器使用setnx 设置同一个key_Redisson分布式锁的简单使用
  8. jenkins 插件目录_Windows下allure+pytest+jenkins集成手册!
  9. 浅谈抖音下拉词框优化推广的优势
  10. 腐蚀rust图纸怎么找_怎么解决变压器油滤油机的温差效应?在这里可以得到解决...
  11. macOS 12兼容机型列表 想知道你的Mac是否支持macOS Monterey吗?
  12. css 设置背景图一半_CSS背景颜色 背景图片 居中 重复 固定样式background经验篇
  13. 【Jquery练习】tab栏切换
  14. 什么是url,herf和src的区别
  15. 测试用例-------邮箱注册
  16. 【王道考研】吸烟者问题
  17. ubuntu18连不上安卓手机的USB网络共享
  18. 列表过滤(百度搜索框用vue来实现)
  19. 这所计算机实力顶尖的大学,也成立人工智能学院
  20. python-opencv 边缘检测

热门文章

  1. CE认证和FCC认证区别
  2. GC 日志解读与分析:千淘万漉虽辛苦,吹尽狂沙始到金
  3. PE中的import table/IAT 分析
  4. 在Web项目中保存会话的两种方法:Cookie和Session
  5. git 配置 ssh 之后还需要登录
  6. java 列表数据List通过模板导出excel表和word表
  7. 收银机和服务器连接不上显示单机,这个收银机修理攻略我秒速收藏了
  8. 群晖执行php,群晖已发布DSM更新对PHPMailer中的漏洞进行修复
  9. webpack2配置浏览器自动刷新
  10. 《傅雷家书》读书心得