接受上文Spring Bean生命周期
应用程序在运转进程中能否去读取当时体系的环境变量或体系特点?
这里涉及到一个十分重要的接口Environment,
System.getenv,System.getProperties都是获取当时体系环境变量,
Environment接口的完结类AbstractEnvironment,AbstractEnvironment的完结类StandardEnvironment,
在当时容器运转之前或运转前置的某些办法里边的时分,就会调用这些办法将环境变量或体系特点放到environment里边去,便利应用程序后续进行调用,比方springmvc init-param指定的初始化办法读取环境变量之后,放到environment中去,这就是environment目标存在的含义。
AbstractApplicationContext这个类refresh办法中包括13个办法,refresh是Spring框架最核心的办法之一,
履行下面的代码,debug来看下创立目标的进程,
super调用父类的构造办法,相当于做了一些特点值的设置,
设置xml配置文件路径,便利后边进行读取和加载。
refresh办法调用prepareRefresh是改写前的预备作业:设置关闭和活跃的标志位。
细节的东西不想看,不要紧,但要知道这个是前期做一些预备作业,便利后边创立目标。
配置文件通过读取之后要放到容器里边去,所以第一步先应该有对应的容器工厂或者有bean工厂,当有了BeanFactory之后,才干进行相关的加载作业,所以第一步应该先创立一个容器,当把容器创立好了之后,下一步才读取配置文件。
obtainFreshBeanFactory.refreshBeanFactory,这个办法里边,先判别容器里边有没有bean工厂,如果有的话,销销毁,如果没有的话,先创立一个bean工厂,由于需求先有bean工厂之后,才干完结当时目标的加载作业。
有了bean工厂之后,设置下序列化的id和自定义配置下工厂的特点值,这样就完结了整个工厂的创立作业。
当完结创立作业之后,第二步loadBeanDefinitions是加载配置文件,由于这个配置文件中有1个bean,所以当履行完这样的加载作业之后,beanDefinitionMap和beanDefinitionNames里边有一个bean,
现在已经把bean目标转化成了bean definition了,下一步该调用beanFactoryPostProcessor进行增强处理,
prepareBeanFactory给beanfactory做预备作业,由于刚刚new了一个目标,还没有给beanFactory做任何特点赋值操作,这个办法就是给beanFactory做一些初始化作业即给当时的beanFactory设置某些详细的特点值。
这是一个模版办法,留给子类进行扩展的。
接下来履行beanFactoryPostProcessor,当这个过程履行完了之后,下一步该实例化了,
在进行实例化的时分,相对而言会比较复杂,实例化的时分包括十分多的过程。
在实例化之前需求做什么预备作业?
要提早把后边需求用到的beanPostProcessor预备好,如果想在整个bean的spring生命周期里边,在不同的阶段做不同的处理作业,监听器 、监听事件、多播器等这些东西都要提早预备好,只要把这些预备好之后,才干进行后续的调用作业,这是一整个流程,不行能用的时分再预备。
这一步是注册beanPostProcessor,这是还没有履行,仅仅先提早预备好。
如果是SpringMVC项目,messagesource就是用来做国际化的操作的。
初始化当时应用程序的事件多播器,
注册监听器。
在实例化之前一切需求做的预备作业都做完了,这几个办法都是预先的预备作业。
接下来该实例化了,实例化一切剩余的非懒加载的单例目标,
finishBeanFactoryInitialization.preInstantiateSingletons该办法是实例化剩余的单例目标,总算要开始实例化了。
当时容器里边有一个bean,目标是把这个bean放到一个集合里边去。
首先看容器里边有没有这个bean,
getBean(beanName).doGetBean
默认情况下都是单例的,
通过反射的方式创立详细的bean目标,
获取到对应的构造器目标,
获取实例化的策略而且进行实例化,
获取到构造器并实例化,
实例化的时分,仅仅在堆中开辟内存空间并没有给特点赋值,
接下来是填充特点,
在履行populateBean办法之前,当时bean目标这3个值都等于空,
履行完之后,name完结了特点填充,但beanName不会填充,由于beanName是aware接口,现在还没有履行Aware接口的完结类,
接下来履行这些完结了aware接口的办法,
此刻beanName就有了,为什么environment没有设置?
由于在prepareBeanFactory办法中对这个Aware接口进行了忽略,
本身的invokeAwareMethods办法也没有对EnvironmentAware进行处理,
调用每个postProcessBeforeInitialization办法,
履行到这里,此刻就已经是一个完好的目标了,
即履行完getBean(beanName)得到了一个完好的目标了。
由于当时集合里边只要一个目标,所以此刻循环就结束了,当时这个bean完结了实例化且初始化。