在线不卡日本ⅴ一区v二区_精品一区二区中文字幕_天堂v在线视频_亚洲五月天婷婷中文网站

  • <menu id="lky3g"></menu>
  • <style id="lky3g"></style>
    <pre id="lky3g"><tt id="lky3g"></tt></pre>

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

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

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

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

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

    我們來看看ApplicationContext多了哪些功能?

    首先看一下寫法上的不同。

    使用BeanFactory方式加載XML

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

    使用ApplicationContext方式加載XML

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

    我們開始點(diǎn)開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ù)組的形式傳入,對解析及功能實(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ù)組中包含特殊符號,如${var},那么在resolvePath方法中會搜尋匹配的系統(tǒng)變量并替換。

    擴(kuò)展功能

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

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

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

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

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

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

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

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

    obtainFreshBeanFactory 方法主要用來獲取BeanFactory,剛才說過ApplicationContext擁有BeanFactory的所有功能,這個方法就是實(shí)現(xiàn)BeanFactory的地方,也就是說調(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()) { //銷毀所有單例 destroyBeans(); //重置beanFactory closeBeanFactory(); } try { //創(chuàng)建beanFactory DefaultListableBeanFactory beanFactory = createBeanFactory(); //設(shè)置序列化id beanFactory.setSerializationId(getId()); //定制beanFactory,設(shè)置相關(guān)屬性,包括是否允許覆蓋同名稱不同定義的對象以及循環(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é)一下這個方法的流程:

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

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

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

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

    /** * @author 神秘杰克 * 公眾號: Java菜鳥程序員 * @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來讀取XML文件,這個步驟中首先要做的就是初始化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)); //對beanDefinitionReader進(jìn)行設(shè)置,可以覆蓋 initBeanDefinitionReader(beanDefinitionReader); loadBeanDefinitions(beanDefinitionReader);}

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

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

    功能擴(kuò)展

    我們在完成了配置文件解析后,我們接著進(jìn)入prepareBeanFactory方法。

    protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { //設(shè)置beanFactory的ClassLoader為當(dāng)前context的ClassLoader beanFactory.setBeanClassLoader(getClassLoader()); //設(shè)置beanFactory的表達(dá)式語言處理 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); //為beanFactory增加了一個默認(rèn)的propertyEditor,主要是對bean的屬性等設(shè)置管理的一個工具 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); //添加BeanPostProcessor beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); //設(shè)置幾個忽略自動裝配的接口 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è)置了幾個自動裝配的特殊規(guī)則 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); //增加了ApplicationListenerDetector主要是檢測bean是否實(shí)現(xiàn)了ApplicationListener接口 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); //增加對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()); }}

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

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

    BeanFactory的后處理

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

    激活注冊的BeanFactoryPostProcessor

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

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

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

    首先我們來看一下配置文件:

    ${bean.msg}

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

    application.properties

    bean.msg=hi

    然后我們再進(jìn)行配置文件的配置。

    application.properties

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

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

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

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

    2.使用自定義BeanFactoryPostProcessor

    我們自己實(shí)現(xiàn)一個自定義BeanFactoryPostProcessor,去除我們不想要顯示的屬性值的功能來展示自定義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()); } }}

    啟動類:

    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=’*****’}

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

    激活BeanFactoryPostProcessor

    我們在了解了BeanFactoryPostProcessor的用法之后就可以繼續(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í)行過的BeanFactoryPostProcessor存儲在processedBeans,防止重復(fù)執(zhí)行 Set processedBeans = new HashSet(); //對BeanDefinitionRegistry類型進(jìn)行處理 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; // 用來存放BeanFactoryPostProcessor對象 List regularPostProcessors = new ArrayList(); // 用來存放BeanDefinitionRegistryPostProcessor對象 // 方便統(tǒng)一執(zhí)行實(shí)現(xiàn)了BeanDefinitionRegistryPostProcessor接口父類的方法 List registryProcessors = new ArrayList(); // 處理外部定義的BeanFactoryPostProcessor,將BeanDefinitionRegistryPostProcessor與BeanFactoryPostProcessor區(qū)分開 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; //對于BeanDefinitionRegistryPostProcessor類型,需要先調(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接口的類名 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { //判斷當(dāng)前類是否實(shí)現(xiàn)了PriorityOrdered接口 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //將BeanDefinitionRegistryPostProcessor類型存入currentRegistryProcessors中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); // 提前存放到processedBeans,避免重復(fù)執(zhí)行,但是此處還未執(zhí)行 processedBeans.add(ppName); } } //對currentRegistryProcessors集合中的BeanDefinitionRegistryPostProcessor類型進(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í)行過程中添加了BeanDefinitionRegistryPostProcessor // 而下面處理BeanFactoryPostProcessor的時候又不需要重復(fù)獲取了是為什么呢? // 因?yàn)樘砑覤eanFactoryPostProcessor與BeanDefinitionRegistryPostProcessor只能在BeanDefinitionRegistryPostProcessor中添加,在BeanFactoryPostProcessor是無法添加的 for (String ppName : postProcessorNames) { // 判斷當(dāng)前bean沒有被執(zhí)行過,并且實(shí)現(xiàn)了Ordered接口 if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { //如果BeanFactory中沒有該Bean則會去創(chuàng)建該Bean currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(currentRegistryProcessors, beanFactory); registryProcessors.addAll(currentRegistryProcessors); invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); currentRegistryProcessors.clear(); //最后處理沒有實(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類型,則直接執(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(); // 用于存放無排序的BeanFactoryPostProcessor名稱 List nonOrderedPostProcessorNames = new ArrayList(); for (String ppName : postProcessorNames) { // 如果已經(jīng)執(zhí)行過了,則不做處理 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); } //如果沒有排序則添加到指定集合 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)用其他沒有排序的 BeanFactoryPostProcessor。 List nonOrderedPostProcessors = new ArrayList(nonOrderedPostProcessorNames.size()); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 清空緩存 beanFactory.clearMetadataCache();}

    注冊BeanPostProcessor

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

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

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

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

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

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

    public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { //獲取所有實(shí)現(xiàn)BeanPostProcessor接口的類 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); //注冊一個 BeanPostProcessorChecker,用來記錄 bean 在 BeanPostProcessor 實(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ù)不同類型進(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í)行注冊實(shí)現(xiàn)了 PriorityOrdered 的 BeanPostProcessors sortPostProcessors(priorityOrderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //注冊實(shí)現(xiàn)Ordered接口的BeanPostProcessors List orderedPostProcessors = new ArrayList(orderedPostProcessorNames.size()); for (String ppName : orderedPostProcessorNames) { //拿到ppName對應(yīng)的BeanPostProcessor實(shí)例對象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); //將ppName對應(yīng)的BeanPostProcessor實(shí)例對象添加到orderedPostProcessors, 準(zhǔn)備執(zhí)行注冊 orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { //如果ppName對應(yīng)的bean實(shí)例也實(shí)現(xiàn)了MergedBeanDefinitionPostProcessor接口,則添加到該集合中 internalPostProcessors.add(pp); } } //對orderedPostProcessors進(jìn)行排序并注冊 sortPostProcessors(orderedPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, orderedPostProcessors); //注冊所有常規(guī)的BeanPostProcessors,過程同上 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); //注冊所有mergedBeanDefinitionPostProcessor類型的BeanPostProcessor,并非重復(fù)注冊 //在beanFactory.addBeanPostProcessor中會先移除已經(jīng)存在的BeanPostProcessor sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // 添加ApplicationListener探測器 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 { //如果用戶并沒有定義配置文件,那么使用臨時的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,否則就會獲取不到自定義資源配置。

    初始化ApplicationEventMulticaster

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

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

    protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); //判斷容器中是否存在BeanDefinitionName為applicationEventMulticaster的bd,也就是自定義的事件監(jiān)聽多路廣播器,必須實(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 { //如果沒有,則默認(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)聽器并在合適的時候調(diào)用監(jiān)聽器,我們進(jìn)入默認(rèn)的廣播器實(shí)現(xiàn)類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事件的時候會默認(rèn)使用SimpleApplicationEventMulticaster的multicastEvent來廣播事件,遍歷所有監(jiān)聽器,并使用監(jiān)聽器中的onApplicationEvent方法來進(jìn)行監(jiān)聽器的處理。而對于每個監(jiān)聽器來說其實(shí)都可以獲取到產(chǎn)生的事件,但是是否進(jìn)行處理則由事件監(jiān)聽器決定。

    注冊監(jiān)聽器

    我們反復(fù)提到了監(jiān)聽器,我們接下來看一下Spring注冊監(jiān)聽器的時候又做了哪些邏輯操作?

    protected void registerListeners() { // 首先注冊靜態(tài)的指定的監(jiān)聽器,注冊的是特殊的事件監(jiān)聽器,而不是配置中的bean for (ApplicationListener listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 這里不會初始化FactoryBean,我們需要保留所有的普通bean // 不會實(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)聽器注冊到廣播組中,那些在bean配置文件中實(shí)現(xiàn)了ApplicationListener接口的類還沒有實(shí)例化,所以此時只是將name保存到了廣播組中,將這些監(jiān)聽器注冊到廣播組中的操作時在bean的后置處理器中完成的,那時候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之前沒有注冊解析器,則注冊默認(rèn)的解析器,例如${}解析成真正的屬性:主要用于注解屬性值的解析 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } //處理 @EnableLoadTimeWeaving 或 標(biāo)記的類 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } //臨時類加載器設(shè)置為空 beanFactory.setTempClassLoader(null); //凍結(jié)所有的bean定義,說明注冊的bean定義將不被修改或者進(jìn)一步處理 beanFactory.freezeConfiguration(); //初始化剩下的單例實(shí)例(非惰性) beanFactory.preInstantiateSingletons();}

    首先,我們先了解下ConversionService類所提供的作用。

    1.ConversionService的設(shè)置

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

    2.凍結(jié)配置

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

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

    3.初始化延遲加載

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

    public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace(“Pre-instantiating singletons in ” + this); } //創(chuàng)建beanDefinitionNames的副本beanNames用于后續(xù)的遍歷,以允許init等方法注冊新的bean定義 List beanNames = new ArrayList(this.beanDefinitionNames); //遍歷beanNames,觸發(fā)所有非懶加載單例bean的初始化 for (String beanName : beanNames) { //獲取beanName對應(yīng)的MergedBeanDefinition RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); //bd對應(yīng)的不是抽象類 && 并且是單例 && 并且不是懶加載 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { //判斷是否為FactoryBean if (isFactoryBean(beanName)) { //通過前綴&和beanName拿到Bean Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); //如果為FactoryBean if (bean instanceof FactoryBean) { final FactoryBean factory = (FactoryBean) bean; //判斷這個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()); } //如果希望急切的初始化,則通過beanName獲取bean實(shí)例 if (isEagerInit) { getBean(beanName); } } } else { //如果beanName對應(yīng)的bean不是FactoryBean,只是普通Bean,通過beanName獲取bean實(shí)例 getBean(beanName); } } } //遍歷beanNames,觸發(fā)所有SmartInitializingSingleton的后初始化回調(diào) for (String beanName : beanNames) { //拿到beanName對應(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)類的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會保證在啟動時候調(diào)用其start方法開始聲明周期,并在Spring關(guān)閉時候調(diào)用stop方法來結(jié)束聲明周期。通常用來配置后臺程序,在啟動后一直運(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)聽器 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. LiveBeansView.registerApplicationContext(this);}

    1.initLifecycleProcessor

    當(dāng)ApplicationContext啟動或停止時,它會通過LifecycleProcessor來和所有聲明的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)的生命周期處理器,注冊到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

    啟動所有實(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初始化的時候,要通過Spring中的發(fā)布機(jī)制來發(fā)出ContextRefreshedEvent事件,以保證對應(yīng)的監(jiān)聽器可以做進(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)聽器 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } //通過parent發(fā)布事件 if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } }}

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

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

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

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

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

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

    相關(guān)推薦

    聯(lián)系我們

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