接受上文Spring Bean生命周期

应用程序在运转进程中能否去读取当时体系的环境变量或体系特点?

这里涉及到一个十分重要的接口Environment,

System.getenv,System.getProperties都是获取当时体系环境变量

Environment接口的完结类AbstractEnvironment,AbstractEnvironment的完结类StandardEnvironment,

Spring Bean实例化和初始化的过程

Spring Bean实例化和初始化的过程

在当时容器运转之前或运转前置的某些办法里边的时分,就会调用这些办法将环境变量或体系特点放到environment里边去,便利应用程序后续进行调用,比方springmvc init-param指定的初始化办法读取环境变量之后,放到environment中去,这就是environment目标存在的含义。

AbstractApplicationContext这个类refresh办法中包括13个办法,refresh是Spring框架最核心的办法之一,

履行下面的代码,debug来看下创立目标的进程,

Spring Bean实例化和初始化的过程

Spring Bean实例化和初始化的过程

super调用父类的构造办法,相当于做了一些特点值的设置,

Spring Bean实例化和初始化的过程

设置xml配置文件路径,便利后边进行读取和加载。

refresh办法调用prepareRefresh是改写前的预备作业:设置关闭和活跃的标志位。

细节的东西不想看,不要紧,但要知道这个是前期做一些预备作业,便利后边创立目标。

Spring Bean实例化和初始化的过程

配置文件通过读取之后要放到容器里边去,所以第一步先应该有对应的容器工厂或者有bean工厂,当有了BeanFactory之后,才干进行相关的加载作业,所以第一步应该先创立一个容器,当把容器创立好了之后,下一步才读取配置文件。

Spring Bean实例化和初始化的过程

obtainFreshBeanFactory.refreshBeanFactory,这个办法里边,先判别容器里边有没有bean工厂,如果有的话,销销毁,如果没有的话,先创立一个bean工厂,由于需求先有bean工厂之后,才干完结当时目标的加载作业。

有了bean工厂之后,设置下序列化的id和自定义配置下工厂的特点值,这样就完结了整个工厂的创立作业。

当完结创立作业之后,第二步loadBeanDefinitions是加载配置文件,由于这个配置文件中有1个bean,所以当履行完这样的加载作业之后,beanDefinitionMap和beanDefinitionNames里边有一个bean,

Spring Bean实例化和初始化的过程

现在已经把bean目标转化成了bean definition了,下一步该调用beanFactoryPostProcessor进行增强处理,

Spring Bean实例化和初始化的过程

prepareBeanFactory给beanfactory做预备作业,由于刚刚new了一个目标,还没有给beanFactory做任何特点赋值操作,这个办法就是给beanFactory做一些初始化作业即给当时的beanFactory设置某些详细的特点值。

Spring Bean实例化和初始化的过程

Spring Bean实例化和初始化的过程

这是一个模版办法,留给子类进行扩展的。

Spring Bean实例化和初始化的过程

接下来履行beanFactoryPostProcessor,当这个过程履行完了之后,下一步该实例化了,

在进行实例化的时分,相对而言会比较复杂,实例化的时分包括十分多的过程。

在实例化之前需求做什么预备作业?

要提早把后边需求用到的beanPostProcessor预备好,如果想在整个bean的spring生命周期里边,在不同的阶段做不同的处理作业,监听器 、监听事件、多播器等这些东西都要提早预备好,只要把这些预备好之后,才干进行后续的调用作业,这是一整个流程,不行能用的时分再预备。

Spring Bean实例化和初始化的过程

这一步是注册beanPostProcessor,这是还没有履行,仅仅先提早预备好。

Spring Bean实例化和初始化的过程

如果是SpringMVC项目,messagesource就是用来做国际化的操作的。

Spring Bean实例化和初始化的过程
初始化当时应用程序的事件多播器,

Spring Bean实例化和初始化的过程
注册监听器。

在实例化之前一切需求做的预备作业都做完了,这几个办法都是预先的预备作业。

Spring Bean实例化和初始化的过程
接下来该实例化了,实例化一切剩余的非懒加载的单例目标,

finishBeanFactoryInitialization.preInstantiateSingletons该办法是实例化剩余的单例目标,总算要开始实例化了。

当时容器里边有一个bean,目标是把这个bean放到一个集合里边去。

首先看容器里边有没有这个bean,

getBean(beanName).doGetBean

Spring Bean实例化和初始化的过程

默认情况下都是单例的,

Spring Bean实例化和初始化的过程
Spring Bean实例化和初始化的过程

通过反射的方式创立详细的bean目标,

Spring Bean实例化和初始化的过程

获取到对应的构造器目标,

Spring Bean实例化和初始化的过程
Spring Bean实例化和初始化的过程

获取实例化的策略而且进行实例化,

Spring Bean实例化和初始化的过程
Spring Bean实例化和初始化的过程

获取到构造器并实例化,

Spring Bean实例化和初始化的过程

实例化的时分,仅仅在堆中开辟内存空间并没有给特点赋值,

Spring Bean实例化和初始化的过程

接下来是填充特点,

Spring Bean实例化和初始化的过程

在履行populateBean办法之前,当时bean目标这3个值都等于空,

Spring Bean实例化和初始化的过程

履行完之后,name完结了特点填充,但beanName不会填充,由于beanName是aware接口,现在还没有履行Aware接口的完结类,

Spring Bean实例化和初始化的过程

接下来履行这些完结了aware接口的办法,

Spring Bean实例化和初始化的过程

此刻beanName就有了,为什么environment没有设置?

Spring Bean实例化和初始化的过程

由于在prepareBeanFactory办法中对这个Aware接口进行了忽略,

Spring Bean实例化和初始化的过程

Spring Bean实例化和初始化的过程
本身的invokeAwareMethods办法也没有对EnvironmentAware进行处理,

Spring Bean实例化和初始化的过程
Spring Bean实例化和初始化的过程

调用每个postProcessBeforeInitialization办法,

Spring Bean实例化和初始化的过程

履行到这里,此刻就已经是一个完好的目标了,

Spring Bean实例化和初始化的过程

即履行完getBean(beanName)得到了一个完好的目标了。

由于当时集合里边只要一个目标,所以此刻循环就结束了,当时这个bean完结了实例化且初始化。