免费爱碰视频在线观看,九九精品国产屋,欧美亚洲尤物久久精品,1024在线观看视频亚洲

      Spring源碼之容器的功能擴(kuò)展和refresh方法解析

      Spring源碼之容器的功能擴(kuò)展和refresh方法解析

      容器功能擴(kuò)展和refresh方法解析

      在之前文章中我們了解了關(guān)于Spring中bean的加載流程,并一直使用BeanFactory接口以及它的默認(rèn)實(shí)現(xiàn)類(lèi)XmlBeanFactory,在Spring中還提供了另一個(gè)接口ApplicationContext,用于擴(kuò)展BeanFactory中現(xiàn)有的功能。

      首先BeanFactory和ApplicationContext都是用于加載bean的,但是相比之下,ApplicationContext提供了更多的擴(kuò)展功能,ApplicationContext包含了BeanFactory的所有功能。通常我們會(huì)優(yōu)先使用ApplicationContext。

      我們來(lái)看看ApplicationContext多了哪些功能?

      首先看一下寫(xiě)法上的不同。

      使用BeanFactory方式加載XML

      final BeanFactory beanFactory = new XmlBeanFactory(new ClassPathResource(“spring-config.xml”));

      使用ApplicationContext方式加載XML

      final ApplicationContext applicationContext = new ClassPathXmlApplicationContext(“spring-config.xml”);

      我們開(kāi)始點(diǎn)開(kāi)ClassPathXmlApplicationContext的構(gòu)造函數(shù),進(jìn)行分析。

      public ClassPathXmlApplicationContext(String configLocation) throws BeansException { this(new String[] {configLocation}, true, null);}public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException { super(parent); setConfigLocations(configLocations); if (refresh) { refresh(); }}

      在ClassPathXmlApplicationContext中可以將配置文件路徑以數(shù)組的形式傳入,對(duì)解析及功能實(shí)現(xiàn)都在refresh()方法中實(shí)現(xiàn)。

      設(shè)置配置路徑

      public void setConfigLocations(@Nullable String… locations) { if (locations != null) { Assert.noNullElements(locations, “Config locations must not be null”); this.configLocations = new String[locations.length]; for (int i = 0; i < locations.length; i++) { this.configLocations[i] = resolvePath(locations[i]).trim(); } } else { this.configLocations = null; }}

      此函數(shù)主要解析給定的路徑數(shù)組,如果數(shù)組中包含特殊符號(hào),如${var},那么在resolvePath方法中會(huì)搜尋匹配的系統(tǒng)變量并替換。

      擴(kuò)展功能

      設(shè)置完路徑后,就可以對(duì)文件進(jìn)行解析和各種功能的實(shí)現(xiàn),可以說(shuō)在refresh方法中幾乎包含了ApplicationContext中提供的全部功能,而且此函數(shù)的邏輯也十分清晰,可以很容易分析對(duì)應(yīng)層次和邏輯。

      public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 準(zhǔn)備刷新的上下文環(huán)境,包括設(shè)置啟動(dòng)時(shí)間,是否激活標(biāo)識(shí)位 // 初始化屬性源(property source)配置 prepareRefresh(); // 初始化BeanFactory 并進(jìn)行xml文件讀取 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 對(duì)BeanFactory進(jìn)行各種功能填充 prepareBeanFactory(beanFactory); try { // 子類(lèi)覆蓋方法做額外的處理 postProcessBeanFactory(beanFactory); // 激活各種BeanFactory處理器 invokeBeanFactoryPostProcessors(beanFactory); // 注冊(cè)攔截bean創(chuàng)建的bean處理器,只是注冊(cè),具體調(diào)用在getBean中 registerBeanPostProcessors(beanFactory); // 為上下文初始化Message源,國(guó)際化處理 initMessageSource(); // 初始化應(yīng)用消息廣播器,并放入applicationEventMulticaster bean中 initApplicationEventMulticaster(); // 留給子類(lèi)來(lái)初始化其他的bean onRefresh(); // 在所有注冊(cè)的bean中查找Listener bean,注冊(cè)到消息廣播器中 registerListeners(); // 初始化剩下的單例bean (非惰性) finishBeanFactoryInitialization(beanFactory); //完成刷新過(guò)程,通知生命周期處理器LifecycleProcessor刷新過(guò)程,同時(shí)發(fā)出ContextRefreshEvent通知?jiǎng)e人 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn(“Exception encountered during context initialization – ” + “cancelling refresh attempt: ” + ex); } // 銷(xiāo)毀已經(jīng)初始化的 singleton 的 Beans,以免有些 bean 會(huì)一直占用資源 destroyBeans(); // 重置活動(dòng)標(biāo)志 cancelRefresh(ex); throw ex; } finally { //重置公共緩存 resetCommonCaches(); } }}

      我們總結(jié)一下初始化的步驟。

    1. 初始化前的準(zhǔn)備工作,例如對(duì)系統(tǒng)屬性或者環(huán)境變量進(jìn)行準(zhǔn)備及驗(yàn)證
    2. 初始化BeanFactory,并對(duì)XML文件進(jìn)行讀取。之前我們說(shuō)過(guò)ClassPathXmlApplicationContext中包含著B(niǎo)eanFactory所提供的一切特征,那么在這一步將會(huì)復(fù)用BeanFactory中的配置文件讀取解析及其他功能,在這一步之后ClassPathXmlApplicationContext就已經(jīng)包含了BeanFactory所提供的功能,也就是可以對(duì)bean進(jìn)行提取等操作
    3. 對(duì)BeanFactory進(jìn)行各種功能填充
    4. 子類(lèi)覆蓋方法做額外的處理。主要用于我們?cè)跇I(yè)務(wù)上做進(jìn)一步擴(kuò)展
    5. 激活各種BeanFactory處理器
    6. 注冊(cè)攔截bean創(chuàng)建的bena處理器,這里僅僅是注冊(cè),真正調(diào)用在getBean中
    7. 為上下文初始化Message源,對(duì)不同語(yǔ)言的消息體進(jìn)行國(guó)際化處理
    8. 初始化應(yīng)用消息廣播器,并放入”applicationEventMulticaster” bean中
    9. 留給子類(lèi)來(lái)初始化其他的bean
    10. 在所有注冊(cè)的bean中查找listener bean,注冊(cè)到消息廣播器中
    11. 初始化剩下的單實(shí)例(非惰性)
    12. 完成刷新過(guò)程,通知生命周期處理器lifecycleProcessor刷新過(guò)程,同時(shí)發(fā)出ContextRefreshEvent來(lái)通知?jiǎng)e人
    13. 環(huán)境準(zhǔn)備

      prepareRefresh方法主要做些準(zhǔn)備工作,比如對(duì)系統(tǒng)屬性及環(huán)境變量的初始化及驗(yàn)證。

    14. initPropertySources
    15. 該方法里面是一個(gè)空實(shí)現(xiàn),主要用于給我們根據(jù)需要去重寫(xiě)該方法,并在方法中進(jìn)行個(gè)性化的屬性處理及設(shè)置。

      protected void initPropertySources() { // For subclasses: do nothing by default.}

    16. validateRequiredProperties 該方法主要對(duì)屬性進(jìn)行驗(yàn)證。默認(rèn)情況下什么也沒(méi)校驗(yàn)。在我們繼承了ClassPathXmlApplicationContext類(lèi)重寫(xiě)了initPropertySources方法后會(huì)進(jìn)行相關(guān)校驗(yàn)。
    17. 加載BeanFactory

      obtainFreshBeanFactory 方法主要用來(lái)獲取BeanFactory,剛才說(shuō)過(guò)ApplicationContext擁有BeanFactory的所有功能,這個(gè)方法就是實(shí)現(xiàn)BeanFactory的地方,也就是說(shuō)調(diào)用完該方法后,applicationContext就擁有了BeanFactory的功能。

      protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { //初始化BeanFactory,并進(jìn)行XML文件讀取,將得到的BeanFactory記錄到當(dāng)前實(shí)體屬性中 refreshBeanFactory(); //返回當(dāng)前實(shí)體的beanFactory屬性 return getBeanFactory();}protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); customizeBeanFactory(beanFactory); loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException(“I/O error parsing bean definition source for ” + getDisplayName(), ex); }}

      我們進(jìn)入AbstractRefreshableApplicationContext#refreshBeanFactory()方法中。

      protected final void refreshBeanFactory() throws BeansException { //判斷是否存在beanFactory if (hasBeanFactory()) { //銷(xiāo)毀所有單例 destroyBeans(); //重置beanFactory closeBeanFactory(); } try { //創(chuàng)建beanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); //設(shè)置序列化id beanFactory.setSerializationId(getId()); //定制beanFactory,設(shè)置相關(guān)屬性,包括是否允許覆蓋同名稱不同定義的對(duì)象以及循環(huán)依賴 customizeBeanFactory(beanFactory); //初始化DocumentReader,進(jìn)行XML讀取和解析 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException(“I/O error parsing bean definition source for ” + getDisplayName(), ex); }}

      總結(jié)一下這個(gè)方法的流程:

    18. 創(chuàng)建DefaultListableBeanFactory。聲明方式為:BeanFactory bf = new XmlBeanFactory(“beanFactoryTest.xml”),其中的XmlBeanFactory繼承自DefaultListableBeanFactory,并提供了XmlBeanDefinitionReader類(lèi)型的reader屬性,也就是說(shuō)DefaultListableBeanFactory是容器的基礎(chǔ),必須首先實(shí)例化,這里就是實(shí)例化DefaultListableBeanFactory的步驟
    19. 指定序列化ID
    20. 定制BeanFactory
    21. 加載BeanDefinition
    22. 使用全局變量記錄BeanFactory類(lèi)實(shí)例
    23. 定制BeanFactory

      首先我們先了解customizeBeanFactory方法,該方法是在基本容器的基礎(chǔ)上,增加了是否允許覆蓋、是否允許擴(kuò)展的設(shè)置。

      protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { //如果不為空,設(shè)置beanFactory對(duì)象響應(yīng)的屬性,含義:是否允許覆蓋同名稱的不同定義的對(duì)象 if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } //如果屬性不為空,設(shè)置給beanFactory對(duì)象相應(yīng)屬性,含義:是否允許bean之間存在循環(huán)依賴 if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); }}

      具體這里只是做了簡(jiǎn)單的判斷,具體設(shè)置屬性的地方,使用子類(lèi)覆蓋即可。例如:

      /** * @author 神秘杰克 * 公眾號(hào): Java菜鳥(niǎo)程序員 * @date 2022/6/12 * @Description 自定義ClassPathXmlApplicationContext */public class MyClassPathXmlApplicationContext extends ClassPathXmlApplicationContext { @Override protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { super.setAllowBeanDefinitionOverriding(false); super.setAllowCircularReferences(false); super.customizeBeanFactory(beanFactory); }}

      加載BeanDefinition

      在初始化了DefaultListableBeanFactory后,我們還需要XmlBeanDefinitionReader來(lái)讀取XML文件,這個(gè)步驟中首先要做的就是初始化XmlBeanDefinitionReader。

      protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { //為指定beanFactory創(chuàng)建XmlBeanDefinitionReader XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); //進(jìn)行環(huán)境變量的設(shè)置 beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); //對(duì)beanDefinitionReader進(jìn)行設(shè)置,可以覆蓋 initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader);}

      初始化了DefaultListableBeanFactory和XmlBeanDefinitionReader后,我們就可以進(jìn)行配置文件的讀取了。最終XmlBeanDefinitionReader所去讀的BeanDefinitionHolder都會(huì)注冊(cè)到DefaultListableBeanFactory中。

      經(jīng)過(guò)該方法后類(lèi)型為DefaultListableBeanFactory中的變量beanFactory已經(jīng)包含了所有解析好的配置。關(guān)于配置文件的讀取這一部分之前文章已經(jīng)講過(guò),這里就不再贅述。

      功能擴(kuò)展

      我們?cè)谕瓿闪伺渲梦募馕龊?,我們接著進(jìn)入prepareBeanFactory方法。

      protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //設(shè)置beanFactory的ClassLoader為當(dāng)前context的ClassLoader beanFactory.setBeanClassLoader(getClassLoader()); //設(shè)置beanFactory的表達(dá)式語(yǔ)言處理 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //為beanFactory增加了一個(gè)默認(rèn)的propertyEditor,主要是對(duì)bean的屬性等設(shè)置管理的一個(gè)工具 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //添加BeanPostProcessor beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //設(shè)置幾個(gè)忽略自動(dòng)裝配的接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); //設(shè)置了幾個(gè)自動(dòng)裝配的特殊規(guī)則 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //增加了ApplicationListenerDetector主要是檢測(cè)bean是否實(shí)現(xiàn)了ApplicationListener接口 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //增加對(duì)AspectJ的支持 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // Set a temporary ClassLoader for type matching. beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } //添加默認(rèn)的系統(tǒng)環(huán)境bean if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); }}

      該方法主要做了幾個(gè)方面的擴(kuò)展:

      • 增加了對(duì)SpEL語(yǔ)言的支持
      • 增加了對(duì)屬性編輯器的支持
      • 增加了一些內(nèi)置類(lèi),比如EnvironmentAware、MessageSourceAware的信息注入
      • 設(shè)置了依賴功能可忽略的接口
      • 注冊(cè)了一些固定依賴的屬性
      • 增加AspectJ的支持
      • 將相關(guān)環(huán)境變量及屬性注冊(cè)以單例模式注冊(cè)

      BeanFactory的后處理

      BeanFactory作為Spring中容器的基礎(chǔ),用于存放所有已經(jīng)加載的bean,為了保證程序的高擴(kuò)展性,Spring針對(duì)BeanFactory做了大量的擴(kuò)展,比如PostProcessor等都是在這里實(shí)現(xiàn)的。

      激活注冊(cè)的BeanFactoryPostProcessor

      在學(xué)習(xí)之前,我們先了解一下BeanFactoryPostProcessor的用法。BeanFactoryPostProcessor接口和BeanPostProcessor類(lèi)似,可以對(duì)bean的定義進(jìn)行處理。也就是說(shuō),Spring IOC容器允許BeanFactoryPostProcessor在容器實(shí)例化任何bean之前讀取配置元數(shù)據(jù),并可以修改它。BeanFactoryPostProcessor可以配置多個(gè),通過(guò)實(shí)現(xiàn)Ordered接口設(shè)置“order”來(lái)控制執(zhí)行順序。

      需要注意的是如果在容器中定義一個(gè)BeanFactoryPostProcessor,它僅僅對(duì)此容器中的bean進(jìn)行后置處理。BeanFactoryPostProcessor不會(huì)對(duì)其他容器中的bean進(jìn)行后置處理。

      1.BeanFactoryPostProcessor的典型應(yīng)用:PropertySourcesPlaceholderConfigurer

      首先我們來(lái)看一下配置文件:

      ${bean.msg}

      在里面我們使用到了變量引用:${bean.msg},這就是Spring的分散配置,我們可以在配置文件中配置該屬性的值。

      application.properties

      bean.msg=hi

      然后我們?cè)龠M(jìn)行配置文件的配置。

      application.properties

      這時(shí)候就明白了,我們通過(guò)PreferencesPlaceholderConfigurer中進(jìn)行獲取我們的配置信息。我們查看該類(lèi)可以知道間接性繼承了BeanFactoryPostProcessor接口。

      當(dāng)Spring加載任何實(shí)現(xiàn)了這個(gè)接口的bean時(shí),都會(huì)在bean工廠加載所有bena的配置之后執(zhí)行postProcessBeanFactory方法。在方法中先后調(diào)用了mergeProperties、convertProperties、processProperties這三個(gè)方法,分別得到配置、將得到的配置進(jìn)行轉(zhuǎn)換為合適的類(lèi)型、最后將配置內(nèi)容告知BeanFactory。

      正是通過(guò)實(shí)現(xiàn)BeanFactoryPostProcessor,BeanFactory會(huì)在實(shí)例化任何bean之前獲得配置信息,從而能夠正確解析bean配置文件中的變量引用。

      PropertySourcesPlaceholderConfigurer已經(jīng)取代了PropertyPlaceholderConfigurer,因?yàn)閰R聚了Environment、多個(gè)PropertySource。所以它能夠控制取值優(yōu)先級(jí)、順序,并且還提供了訪問(wèn)的方法,后期再想獲取也不是問(wèn)題。

      2.使用自定義BeanFactoryPostProcessor

      我們自己實(shí)現(xiàn)一個(gè)自定義BeanFactoryPostProcessor,去除我們不想要顯示的屬性值的功能來(lái)展示自定義BeanFactoryPostProcessor的創(chuàng)建及使用,例如bean定義中我們屏蔽掉‘guapi’、‘shazi’。

      guapi shazi public class SimpleBean { private String userName; private String email; private String address; //getter setter}public class ObscenityRemovingBeanFactoryPostProcessor implements BeanFactoryPostProcessor { private final Set obscenities; public ObscenityRemovingBeanFactoryPostProcessor() { this.obscenities = new HashSet(); } /** * 將所有bean 的參數(shù)中含有 obscenities 集合中的值進(jìn)行屏蔽 */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { String[] beanNames = beanFactory.getBeanDefinitionNames(); for (String beanName : beanNames) { final BeanDefinition beanDefinition = beanFactory.getBeanDefinition(beanName); StringValueResolver valueResolver = strVal -> { if (isObscene(strVal)){ return “*****”; } return strVal; }; final BeanDefinitionVisitor beanDefinitionVisitor = new BeanDefinitionVisitor(valueResolver); beanDefinitionVisitor.visitBeanDefinition(beanDefinition); } } public boolean isObscene(Object value){ String potentialObscenity = value.toString().toUpperCase(); return this.obscenities.contains(potentialObscenity); } public void setObscenities(Set obscenities){ this.obscenities.clear(); for (String obscenity : obscenities) { this.obscenities.add(obscenity.toUpperCase()); } }}

      啟動(dòng)類(lèi):

      public class Test { public static void main(String[] args) { ApplicationContext ac = new ClassPathXmlApplicationContext(“beanFactory.xml”); SimpleBean simpleBean = (SimpleBean) ac.getBean(“simpleBean”); System.out.println(simpleBean); }}

      輸出結(jié)果:

      SimpleBean{userName=’jack’, email=’*****’, address=’*****’}

      我們通過(guò)ObscenityRemovingBeanFactoryPostProcessor我們很好的屏蔽掉了我們不想要顯示的屬性。

      激活BeanFactoryPostProcessor

      我們?cè)诹私饬薆eanFactoryPostProcessor的用法之后就可以繼續(xù)回到我們的refresh方法中繼續(xù)研究源碼了。

      進(jìn)入invokeBeanFactoryPostProcessors方法中。

      protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime // (e.g. through an @Bean method registered by ConfigurationClassPostProcessor) if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); }}

      我們繼續(xù)進(jìn)入具體重載方法中invokeBeanFactoryPostProcessors。

      public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List beanFactoryPostProcessors) { // 將已經(jīng)執(zhí)行過(guò)的BeanFactoryPostProcessor存儲(chǔ)在processedBeans,防止重復(fù)執(zhí)行 Set processedBeans = new HashSet(); //對(duì)BeanDefinitionRegistry類(lèi)型進(jìn)行處理 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 用來(lái)存放BeanFactoryPostProcessor對(duì)象 List regularPostProcessors = new ArrayList(); // 用來(lái)存放BeanDefinitionRegistryPostProcessor對(duì)象 // 方便統(tǒng)一執(zhí)行實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口父類(lèi)的方法 List registryProcessors = new ArrayList(); // 處理外部定義的BeanFactoryPostProcessor,將BeanDefinitionRegistryPostProcessor與BeanFactoryPostProcessor區(qū)分開(kāi) for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; //對(duì)于BeanDefinitionRegistryPostProcessor類(lèi)型,需要先調(diào)用此方法,再添加到集合中 registryProcessor.postProcessBeanDefinitionRegistry(registry); registryProcessors.add(registryProcessor); } else { //記錄常規(guī)BeanFactoryPostProcessor regularPostProcessors.add(postProcessor); } } //存放當(dāng)前需要執(zhí)行的BeanDefinitionRegistryPostProcessor List currentRegistryProcessors = new ArrayList(); // 調(diào)用實(shí)現(xiàn) PriorityOrdered 的 BeanDefinitionRegistryPostProcessor。 // 獲取所有實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口的類(lèi)名 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { //判斷當(dāng)前類(lèi)是否實(shí)現(xiàn)了PriorityOrdered接口 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //將BeanDefinitionRegistryPostProcessor類(lèi)型存入currentRegistryProcessors中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 提前存放到processedBeans,避免重復(fù)執(zhí)行,但是此處還未執(zhí)行 processedBeans.add(ppName); } } //對(duì)currentRegistryProcessors集合中的BeanDefinitionRegistryPostProcessor類(lèi)型進(jìn)行排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 添加到registryProcessors集合,用于后續(xù)執(zhí)行父接口的postProcessBeanFactory方法 registryProcessors.addAll(currentRegistryProcessors); // 遍歷集合,執(zhí)行BeanDefinitionRegistryPostProcessor.postProcessBeanDefinitionRegistry()方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); //執(zhí)行完畢后清空該集合 currentRegistryProcessors.clear(); // 接著,調(diào)用實(shí)現(xiàn) Ordered 的 BeanDefinitionRegistryPostProcessors // 這里再次獲取BeanDefinitionRegistryPostProcessor,是因?yàn)橛锌赡茉谏厦娣椒▓?zhí)行過(guò)程中添加了BeanDefinitionRegistryPostProcessor // 而下面處理BeanFactoryPostProcessor的時(shí)候又不需要重復(fù)獲取了是為什么呢? // 因?yàn)樘砑覤eanFactoryPostProcessor與BeanDefinitionRegistryPostProcessor只能在BeanDefinitionRegistryPostProcessor中添加,在BeanFactoryPostProcessor是無(wú)法添加的 for (String ppName : postProcessorNames) { // 判斷當(dāng)前bean沒(méi)有被執(zhí)行過(guò),并且實(shí)現(xiàn)了Ordered接口 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { //如果BeanFactory中沒(méi)有該Bean則會(huì)去創(chuàng)建該Bean currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); //最后處理沒(méi)有實(shí)現(xiàn)Ordered與PriorityOrdered接口的BeanDefinitionRegistryPostProcessor boolean reiterate = true; while (reiterate) { reiterate = false; // 再次獲取BeanDefinitionRegistryPostProcessor postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { // 將本次要執(zhí)行的BeanDefinitionRegistryPostProcessor存放到currentRegistryProcessors currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); } //現(xiàn)在,調(diào)用到目前為止處理的所有處理器的 postProcessBeanFactory 回調(diào)。 invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // BeanFactory如果不歸屬于BeanDefinitionRegistry類(lèi)型,則直接執(zhí)行beanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // 用于存放實(shí)現(xiàn)了priorityOrdered接口的BeanFactoryPostProcessor List priorityOrderedPostProcessors = new ArrayList(); // 用于存放實(shí)現(xiàn)了ordered接口的BeanFactoryPostProcessor名稱 List orderedPostProcessorNames = new ArrayList(); // 用于存放無(wú)排序的BeanFactoryPostProcessor名稱 List nonOrderedPostProcessorNames = new ArrayList(); for (String ppName : postProcessorNames) { // 如果已經(jīng)執(zhí)行過(guò)了,則不做處理 if (processedBeans.contains(ppName)) { // skip – already processed in first phase above } // 如果實(shí)現(xiàn)了PriorityOrdered 則添加 else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } // 如果實(shí)現(xiàn)了Ordered 則添加 else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } //如果沒(méi)有排序則添加到指定集合 else { nonOrderedPostProcessorNames.add(ppName); } } // 首先調(diào)用實(shí)現(xiàn) PriorityOrdered 的 BeanFactoryPostProcessor。 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 然后調(diào)用實(shí)現(xiàn) Ordered 的 BeanFactoryPostProcessors。 List orderedPostProcessors = new ArrayList(orderedPostProcessorNames.size()); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(orderedPostProcessors, beanFactory); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 最后調(diào)用其他沒(méi)有排序的 BeanFactoryPostProcessor。 List nonOrderedPostProcessors = new ArrayList(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 清空緩存 beanFactory.clearMetadataCache();}

      注冊(cè)BeanPostProcessor

      了解了BeanFactoryPostProcessors的調(diào)用后,我們現(xiàn)在來(lái)了解下BeanPostProcessor,這里僅僅是注冊(cè),并不是調(diào)用。真正的調(diào)用在bean實(shí)例化階段進(jìn)行的。

      在BeanFactory中并沒(méi)有實(shí)現(xiàn)后處理器的自動(dòng)注冊(cè)功能,所以在調(diào)用的時(shí)候如果沒(méi)有進(jìn)行主動(dòng)注冊(cè)則是不能夠使用的。但是在ApplicationContext中添加了主動(dòng)注冊(cè)功能。

      比如自定義這樣的后處理器:

      public class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { @Override public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { System.out.println(“===”); return null; }}

      在使用ApplicationContext方式獲取bean的時(shí)候會(huì)在獲取之前打印出“===”,在BeanFactory方式進(jìn)行bean的加載是不會(huì)有該打印的。

      這個(gè)特性就是在registerBeanPostProcessors中實(shí)現(xiàn)的。

      public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //獲取所有實(shí)現(xiàn)BeanPostProcessor接口的類(lèi) String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); //注冊(cè)一個(gè) BeanPostProcessorChecker,用來(lái)記錄 bean 在 BeanPostProcessor 實(shí)例化時(shí)的信息 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); //區(qū)分實(shí)現(xiàn)不同接口的 BeanPostProcessors List priorityOrderedPostProcessors = new ArrayList(); List internalPostProcessors = new ArrayList(); List orderedPostProcessorNames = new ArrayList(); List nonOrderedPostProcessorNames = new ArrayList(); //根據(jù)不同類(lèi)型進(jìn)行add for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 排序后執(zhí)行注冊(cè)實(shí)現(xiàn)了 PriorityOrdered 的 BeanPostProcessors sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //注冊(cè)實(shí)現(xiàn)Ordered接口的BeanPostProcessors List orderedPostProcessors = new ArrayList(orderedPostProcessorNames.size()); for (String ppName : orderedPostProcessorNames) { //拿到ppName對(duì)應(yīng)的BeanPostProcessor實(shí)例對(duì)象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //將ppName對(duì)應(yīng)的BeanPostProcessor實(shí)例對(duì)象添加到orderedPostProcessors, 準(zhǔn)備執(zhí)行注冊(cè) orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { //如果ppName對(duì)應(yīng)的bean實(shí)例也實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor接口,則添加到該集合中 internalPostProcessors.add(pp); } } //對(duì)orderedPostProcessors進(jìn)行排序并注冊(cè) sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); //注冊(cè)所有常規(guī)的BeanPostProcessors,過(guò)程同上 List nonOrderedPostProcessors = new ArrayList(nonOrderedPostProcessorNames.size()); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); //注冊(cè)所有mergedBeanDefinitionPostProcessor類(lèi)型的BeanPostProcessor,并非重復(fù)注冊(cè) //在beanFactory.addBeanPostProcessor中會(huì)先移除已經(jīng)存在的BeanPostProcessor sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // 添加ApplicationListener探測(cè)器 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));}

      初始化消息資源

      在initMessageSource中主要功能是提取配置文件中的messageSource,并將其記錄在Spring容器中,也就是ApplicationContext中。如果用戶未設(shè)置資源文件的話,則獲取Spring默認(rèn)的配置delegatingMessageSource。

      protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // Bean 的名稱必須要是 messageSource if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { //MESSAGE_SOURCE_BEAN_NAME = messageSource this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // Make MessageSource aware of parent MessageSource. if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { // Only set parent context as parent MessageSource if no parent MessageSource // registered already. hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace(“Using MessageSource [” + this.messageSource + “]”); } } else { //如果用戶并沒(méi)有定義配置文件,那么使用臨時(shí)的DelegatingMessageSource以便于作為調(diào)用getMessage的返回 DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isTraceEnabled()) { logger.trace(“No ‘” + MESSAGE_SOURCE_BEAN_NAME + “‘ bean, using [” + this.messageSource + “]”); } }}

      這里規(guī)定資源文件必須為messageSource,否則就會(huì)獲取不到自定義資源配置。

      初始化ApplicationEventMulticaster

      initApplicationEventMulticaster方法實(shí)現(xiàn)比較簡(jiǎn)單,存在兩種情況:

      • 如果用戶自定義了事件廣播器,那么就是用用戶自定義的事件廣播器
      • 如果用戶沒(méi)有自定義事件廣播器,那么使用默認(rèn)的ApplicationEventMulticaster

      protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //判斷容器中是否存在BeanDefinitionName為applicationEventMulticaster的bd,也就是自定義的事件監(jiān)聽(tīng)多路廣播器,必須實(shí)現(xiàn)ApplicationEventMulticaster接口 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isTraceEnabled()) { logger.trace(“Using ApplicationEventMulticaster [” + this.applicationEventMulticaster + “]”); } } else { //如果沒(méi)有,則默認(rèn)采用SimpleApplicationEventMulticaster this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isTraceEnabled()) { logger.trace(“No ‘” + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + “‘ bean, using ” + “[” + this.applicationEventMulticaster.getClass().getSimpleName() + “]”); } }}

      最后,作為廣播器,一定是用于存放監(jiān)聽(tīng)器并在合適的時(shí)候調(diào)用監(jiān)聽(tīng)器,我們進(jìn)入默認(rèn)的廣播器實(shí)現(xiàn)類(lèi)SimpleApplicationEventMulticaster中看一下。

      看到如下方法:

      public void multicastEvent(final ApplicationEvent event, @Nullable ResolvableType eventType) { ResolvableType type = (eventType != null ? eventType : resolveDefaultEventType(event)); Executor executor = getTaskExecutor(); for (ApplicationListener listener : getApplicationListeners(event, type)) { if (executor != null) { executor.execute(() -> invokeListener(listener, event)); } else { invokeListener(listener, event); } }}

      可以推斷,當(dāng)產(chǎn)生Spring事件的時(shí)候會(huì)默認(rèn)使用SimpleApplicationEventMulticaster的multicastEvent來(lái)廣播事件,遍歷所有監(jiān)聽(tīng)器,并使用監(jiān)聽(tīng)器中的onApplicationEvent方法來(lái)進(jìn)行監(jiān)聽(tīng)器的處理。而對(duì)于每個(gè)監(jiān)聽(tīng)器來(lái)說(shuō)其實(shí)都可以獲取到產(chǎn)生的事件,但是是否進(jìn)行處理則由事件監(jiān)聽(tīng)器決定。

      注冊(cè)監(jiān)聽(tīng)器

      我們反復(fù)提到了監(jiān)聽(tīng)器,我們接下來(lái)看一下Spring注冊(cè)監(jiān)聽(tīng)器的時(shí)候又做了哪些邏輯操作?

      protected void registerListeners() { // 首先注冊(cè)靜態(tài)的指定的監(jiān)聽(tīng)器,注冊(cè)的是特殊的事件監(jiān)聽(tīng)器,而不是配置中的bean for (ApplicationListener listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 這里不會(huì)初始化FactoryBean,我們需要保留所有的普通bean // 不會(huì)實(shí)例化這些bean,讓后置處理器可以感知到它們 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 現(xiàn)在有了事件廣播組,發(fā)布之前的應(yīng)用事件 Set earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } }}

      只是將一些特殊的監(jiān)聽(tīng)器注冊(cè)到廣播組中,那些在bean配置文件中實(shí)現(xiàn)了ApplicationListener接口的類(lèi)還沒(méi)有實(shí)例化,所以此時(shí)只是將name保存到了廣播組中,將這些監(jiān)聽(tīng)器注冊(cè)到廣播組中的操作時(shí)在bean的后置處理器中完成的,那時(shí)候bean的實(shí)例化已經(jīng)完成了。

      初始化非延遲加載單例

      完成BeanFactory的初始化工作,其中包括ConversionService的設(shè)置、配置凍結(jié)以及非延遲加載的bean的初始化工作。

      protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化此上下文的轉(zhuǎn)換服務(wù) if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) && beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) { beanFactory.setConversionService( beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)); } // 如果beanFactory之前沒(méi)有注冊(cè)解析器,則注冊(cè)默認(rèn)的解析器,例如${}解析成真正的屬性:主要用于注解屬性值的解析 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } //處理 @EnableLoadTimeWeaving 或 標(biāo)記的類(lèi) String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } //臨時(shí)類(lèi)加載器設(shè)置為空 beanFactory.setTempClassLoader(null); //凍結(jié)所有的bean定義,說(shuō)明注冊(cè)的bean定義將不被修改或者進(jìn)一步處理 beanFactory.freezeConfiguration(); //初始化剩下的單例實(shí)例(非惰性) beanFactory.preInstantiateSingletons();}

      首先,我們先了解下ConversionService類(lèi)所提供的作用。

      1.ConversionService的設(shè)置

      之前我們提到可以用自定義類(lèi)型轉(zhuǎn)換器把String類(lèi)型轉(zhuǎn)換為Date,在Spring中也提供了使用Converter來(lái)進(jìn)行轉(zhuǎn)換。

      2.凍結(jié)配置

      凍結(jié)所有的bean定義,說(shuō)明注冊(cè)的bean定義將不被修改或者進(jìn)行任何一步的處理。

      public void freezeConfiguration() { this.configurationFrozen = true; this.frozenBeanDefinitionNames = StringUtils.toStringArray(this.beanDefinitionNames);}

      3.初始化延遲加載

      ApplicationContext實(shí)現(xiàn)的默認(rèn)行為就是在啟動(dòng)時(shí)將所有單例bean提前進(jìn)行實(shí)例化。提前實(shí)例化也就意味著作為初始化過(guò)程的一部分,ApplicationContext實(shí)例會(huì)創(chuàng)建并配置所有單例bean,這個(gè)實(shí)例化過(guò)程就是在finishBeanFactoryInitialization方法中的preInstantiateSingletons方法中完成的。

      public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace(“Pre-instantiating singletons in ” + this); } //創(chuàng)建beanDefinitionNames的副本beanNames用于后續(xù)的遍歷,以允許init等方法注冊(cè)新的bean定義 List beanNames = new ArrayList(this.beanDefinitionNames); //遍歷beanNames,觸發(fā)所有非懶加載單例bean的初始化 for (String beanName : beanNames) { //獲取beanName對(duì)應(yīng)的MergedBeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //bd對(duì)應(yīng)的不是抽象類(lèi) && 并且是單例 && 并且不是懶加載 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判斷是否為FactoryBean if (isFactoryBean(beanName)) { //通過(guò)前綴&和beanName拿到Bean Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //如果為FactoryBean if (bean instanceof FactoryBean) { final FactoryBean factory = (FactoryBean) bean; //判斷這個(gè)FactoryBean是否希望急切的初始化 boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction) ((SmartFactoryBean) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean) factory).isEagerInit()); } //如果希望急切的初始化,則通過(guò)beanName獲取bean實(shí)例 if (isEagerInit) { getBean(beanName); } } } else { //如果beanName對(duì)應(yīng)的bean不是FactoryBean,只是普通Bean,通過(guò)beanName獲取bean實(shí)例 getBean(beanName); } } } //遍歷beanNames,觸發(fā)所有SmartInitializingSingleton的后初始化回調(diào) for (String beanName : beanNames) { //拿到beanName對(duì)應(yīng)的bean實(shí)例 Object singletonInstance = getSingleton(beanName); //判斷singletonInstance是否實(shí)現(xiàn)了SmartInitializingSingleton接口 if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; //觸發(fā)SmartInitializingSingleton實(shí)現(xiàn)類(lèi)的afterSingletonsInstantiated方法 if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } }}

      finishRefresh

      在Spring中提供了Lifecycle接口,該接口包含start/stop方法,實(shí)現(xiàn)此接口后Spring會(huì)保證在啟動(dòng)時(shí)候調(diào)用其start方法開(kāi)始聲明周期,并在Spring關(guān)閉時(shí)候調(diào)用stop方法來(lái)結(jié)束聲明周期。通常用來(lái)配置后臺(tái)程序,在啟動(dòng)后一直運(yùn)行(比如MQ)而ApplicationContext最后一步finishRefresh方法就是實(shí)現(xiàn)這一功能。

      protected void finishRefresh() { //清除資源緩存 clearResourceCaches(); //1.為此上下文初始化生命周期處理器 initLifecycleProcessor(); //2.首先將刷新完畢事件傳播到生命周期處理器(觸發(fā)isAutoStartup方法返回true的SmartLifecycle的start方法) getLifecycleProcessor().onRefresh(); //3.推送上下文刷新完畢事件到相應(yīng)的監(jiān)聽(tīng)器 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this);}

      1.initLifecycleProcessor

      當(dāng)ApplicationContext啟動(dòng)或停止時(shí),它會(huì)通過(guò)LifecycleProcessor來(lái)和所有聲明的bean的周期做狀態(tài)更新,而在LifecycleProcessor的使用前首先進(jìn)行初始化。

      protected void initLifecycleProcessor() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //判斷BeanFactory是否已經(jīng)存在生命周期處理器(beanName=lifecycleProcessor) if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) { this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class); if (logger.isTraceEnabled()) { logger.trace(“Using LifecycleProcessor [” + this.lifecycleProcessor + “]”); } } else { //如果不存在,則使用DefaultLifecycleProcessor DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor(); defaultProcessor.setBeanFactory(beanFactory); this.lifecycleProcessor = defaultProcessor; // 并將DefaultLifecycleProcessor作為默認(rèn)的生命周期處理器,注冊(cè)到BeanFactory中 beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); if (logger.isTraceEnabled()) { logger.trace(“No ‘” + LIFECYCLE_PROCESSOR_BEAN_NAME + “‘ bean, using ” + “[” + this.lifecycleProcessor.getClass().getSimpleName() + “]”); } }}

      2.onRefresh

      啟動(dòng)所有實(shí)現(xiàn)了Lifecycle接口的bean

      public void onRefresh() { startBeans(true); this.running = true;}private void startBeans(boolean autoStartupOnly) { Map lifecycleBeans = getLifecycleBeans(); Map phases = new HashMap(); lifecycleBeans.forEach((beanName, bean) -> { if (!autoStartupOnly || (bean instanceof SmartLifecycle && ((SmartLifecycle) bean).isAutoStartup())) { int phase = getPhase(bean); LifecycleGroup group = phases.get(phase); if (group == null) { group = new LifecycleGroup(phase, this.timeoutPerShutdownPhase, lifecycleBeans, autoStartupOnly); phases.put(phase, group); } group.add(beanName, bean); } }); if (!phases.isEmpty()) { List keys = new ArrayList(phases.keySet()); Collections.sort(keys); for (Integer key : keys) { phases.get(key).start(); } }}

      3.publishEvent

      當(dāng)完成ApplicationContext初始化的時(shí)候,要通過(guò)Spring中的發(fā)布機(jī)制來(lái)發(fā)出ContextRefreshedEvent事件,以保證對(duì)應(yīng)的監(jiān)聽(tīng)器可以做進(jìn)一步的邏輯處理。

      protected void publishEvent(Object event, @Nullable ResolvableType eventType) { Assert.notNull(event, “Event must not be null”); //如有必要,將事件裝飾為ApplicationEvent ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { applicationEvent = new PayloadApplicationEvent(this, event); if (eventType == null) { eventType = ((PayloadApplicationEvent) applicationEvent).getResolvableType(); } } // Multicast right now if possible – or lazily once the multicaster is initialized if (this.earlyApplicationEvents != null) { this.earlyApplicationEvents.add(applicationEvent); } else { //使用事件廣播器廣播事件到相應(yīng)的監(jiān)聽(tīng)器 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } //通過(guò)parent發(fā)布事件 if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } }}

      到這里,refresh方法就解析完成了。下一步就是AOP了。

      如果本文對(duì)你有幫助,別忘記給我個(gè)3連 ,點(diǎn)贊,轉(zhuǎn)發(fā),評(píng)論,

      咱們下期見(jiàn)!答案獲取方式:已贊 已評(píng) 已關(guān)~

      學(xué)習(xí)更多JAVA知識(shí)與技巧,關(guān)注與私信博主(03)

      原文出處:https://segmentfault.com/a/1190000041999221

      鄭重聲明:本文內(nèi)容及圖片均整理自互聯(lián)網(wǎng),不代表本站立場(chǎng),版權(quán)歸原作者所有,如有侵權(quán)請(qǐng)聯(lián)系管理員(admin#wlmqw.com)刪除。
      (0)
      用戶投稿
      上一篇 2022年6月20日 06:28
      下一篇 2022年6月20日 06:29

      相關(guān)推薦

      聯(lián)系我們

      聯(lián)系郵箱:admin#wlmqw.com
      工作時(shí)間:周一至周五,10:30-18:30,節(jié)假日休息