一、fsh()概览
首先需要明确,这里调用的fsh()方法是AnnotationConfigServletWebServerApplicationContext上下文,obtainFshBeanFactory()获取的beanFactory实际类型是DefaultListableBeanFactory。
首先我们来看整体代码,fsh()的方法很清晰,因为他将所有的功能封装到了各个方法中。后面我们会一一介绍这些方法。
Override publicvoidfsh()throwsBeansException,IllegalStateException{ synchronized(this.startupShutdownMonitor){ //准备刷新上下文环境。作用就是初始化一些状态和属性,为后面的工作做准备。 ppaRefsh(); //初始化beanFactory,如果需要读取XML配置,也是在这一步完成的。 ConfigurableListableBeanFactorybeanFactory=obtainFshBeanFactory(); //对beanFactory进行各种功能填充 ppaBeanFactory(beanFactory); try{ //对BeanFactory做额外处理。默认没有实现 postProcessBeanFactory(beanFactory); //激活各种BeanFactory后处理器 invokeBeanFactoryPostProcessors(beanFactory); //注册并创建拦截bean创建的bean处理器 gisterBeanPostProcessors(beanFactory); //为上下文初始化Message源,即不同语言的消息体,国际化处理 initMessageSource(); //初始化应用消息广播器,并放入"applicationEventMulticaster"bean中 initApplicationEventMulticaster(); //留给子类来初始化其他的bean onRefsh(); //在所有注册的bean中查找listenerbean,并注册到消息广播器中 gisterListeners(); //初始化剩下的单实例(非惰性) finishBeanFactoryInitialization(beanFactory); //完成刷新过程,通知生命周期处理器lifecycleProcesseor刷新过程,同时发出ContextRefshEvent通知别人。 finishRefsh(); } ...省略无关代码 }
下面简单概括一下上面的初始化步骤
ppaRefsh:初始化前的准备工作,例如对系统属性或者环境变量进行准备及验证。在某些情况下项目的使用需要读取某些系统变量,那么在启动时候,就可以通过准备函数来进行参数的校验。
obtainFshBeanFactory:初始化BeanFactory,并进行XML文件读取(如果需要的话)。这一步之后ApplicationContext就具有BeanFactory所提供的功能,也就是可以进行Bean的提取等基础操作了。
ppaBeanFactory:对BeanFactory进行各种功能填充。
postProcessBeanFactory:对BeanFactory做额外处理。默认没有实现
invokeBeanFactoryPostProcessors:激活各种BeanFactory处理器(调用了各种BeanFactoryPostProcessor)。其中最为关键的是ConfigurationClassPostProcessor,在这里完成了配置类的解析,生成的注入容器中的bean的BeanDefinition。
gisterBeanPostProcessors:注册和创建拦截bean创建的bean处理器。BeanPostProcessor在这一步已经完成了创建。
initMessageSource:为上下文初始化Message源,即对不同语言的消息体进行国际化处理
initApplicationEventMulticaster:初始化应用消息广播器,并放入"applicationEventMulticaster"bean中
onRefsh:留给子类来初始化其他bean
gisterListeners:在所有注册的bean中查找listenerbean,注册到消息广播器中
finishBeanFactoryInitialization:初始化剩下的实例(非惰性),在这里调用了getBean方法,创建了非惰性的bean实例
finishRefsh:完成刷新过程,通知生命周期处理器lifecycleProcesseor刷新过程,同时发出ContextRefshEvent通知别人。
下面我们来分析每一步的具体内容。
二、fsh()详述
1.准备环境-ppaRefsh()
ppaRefsh()方法整体还是比较清晰的,作用就是初始化一些状态和属性,为后面的工作做准备。
具体代码如下:
protectedvoidppaRefsh(){ //Switchtoactive. //设置启动时间,激活刷新状态 this.startupDate=System.curntTimeMillis(); this.closed.set(false); this.active.set(true); if(logger.isDebugEnabled()){ if(logger.isTraceEnabled()){ logger.trace("Refshing"+this); } else{ logger.debug("Refshing"+getDisplayName()); } } //Initializeanyplaceholderpropertysourcesinthecontextenvironment. //留给子类覆盖 initPropertySources(); //Validatethatallpropertiesmarkedasquidasolvable: //seeConfigurablePropertyResolver#setRequidProperties //验证需要的属性文件是否都已经放入环境中 getEnvironment().validateRequidProperties(); //Stop-fshApplicationListeners... //初始化一些属性 if(this.earlyApplicationListeners==null){ this.earlyApplicationListeners=newLinkedHashSet(this.applicationListeners); } else{ //Resetlocalapplicationlistenerstop-fshstate. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } //AllowforthecollectionofearlyApplicationEvents, //tobepublishedoncethemulticasterisavailable... this.earlyApplicationEvents=newLinkedHashSet(); }
这里需要注意的两个方法:
initPropertySources():这个方法是为了给用户自己实现初始化逻辑,可以初始化一些属性资源。因此Spring并没有实现这个方法。
validateRequidProperties():这个方法是对一些启动必须的属性的验证。
我们可以通过实现或者继承ApplicationContext来重写这两个方法,从而完成一些基本属性的校验。
2.加载BeanFactory-obtainFshBeanFactory()
obtainFshBeanFactory()从字面意思就是获取BeanFactory。经过这个方法,BeanFactory就已经被创建完成。
具体代码如下:
protectedConfigurableListableBeanFactoryobtainFshBeanFactory(){ fshBeanFactory(); turngetBeanFactory(); }
而实际上将BeanFactory的创建委托给了fshBeanFactory()方法,fshBeanFactory()方法被两个类实现AbstractRefshableApplicationContext和GenericApplicationContext。我们这里分析的是GenericApplicationContext实现。
GenericApplicationContext.fshBeanFactory()的实现如下:
protectedfinalvoidfshBeanFactory()throwsIllegalStateException{ //CAS设置将刷新状态置为true if(!this.fshed.
本文编辑:佚名
转载请注明出地址 http://www.smartcarf.com/smartcarcx/10661.html