麻豆小视频在线观看_中文黄色一级片_久久久成人精品_成片免费观看视频大全_午夜精品久久久久久久99热浪潮_成人一区二区三区四区

首頁 > 學院 > 開發(fā)設(shè)計 > 正文

Spring4.3.x 容器的刷新過程

2019-11-10 19:44:55
字體:
供稿:網(wǎng)友

概述


SPRing容器體系的繼承結(jié)構(gòu)圖如下。

這里寫圖片描述

從圖中可以看出抽象類AbstractapplicationContext是所有容器類的父類。AbstractApplicationContext實現(xiàn)了它繼承的所有接口方法,并定義了三個用于管理BeanFactory對象的抽象方法,如下

//--------------------------------------------------------------------- // Abstract methods that must be implemented by subclasses //--------------------------------------------------------------------- /** * Subclasses must implement this method to perform the actual configuration load. * The method is invoked by {@link #refresh()} before any other initialization work. * <p>A subclass will either create a new bean factory and hold a reference to it, * or return a single BeanFactory instance that it holds. In the latter case, it will * usually throw an IllegalStateException if refreshing the context more than once. * @throws BeansException if initialization of the bean factory failed * @throws IllegalStateException if already initialized and multiple refresh * attempts are not supported */ protected abstract void refreshBeanFactory() throws BeansException, IllegalStateException; /** * Subclasses must implement this method to release their internal bean factory. * This method gets invoked by {@link #close()} after all other shutdown work. * <p>Should never throw an exception but rather log shutdown failures. */ protected abstract void closeBeanFactory(); /** * Subclasses must return their internal bean factory here. They should implement the * lookup efficiently, so that it can be called repeatedly without a performance penalty. * <p>Note: Subclasses should check whether the context is still active before * returning the internal bean factory. The internal factory should generally be * considered unavailable once the context has been closed. * @return this application context's internal bean factory (never {@code null}) * @throws IllegalStateException if the context does not hold an internal bean factory yet * (usually if {@link #refresh()} has never been called) or if the context has been * closed already * @see #refreshBeanFactory() * @see #closeBeanFactory() */ @Override public abstract ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException;

小技巧:告訴大家如何查看一個抽象類未實現(xiàn)的接口方法有哪些,比如上面的AbstractApplicationContext抽象類。我創(chuàng)建了一個MyApplicationContext 類,如果未實現(xiàn)任何方法,IDE會提醒我實現(xiàn)父類中未實現(xiàn)的方法,代碼如下。

public class MyApplicationContext extends AbstractApplicationContext { @Override protected void refreshBeanFactory() throws BeansException, IllegalStateException { } @Override protected void closeBeanFactory() { } @Override public ConfigurableListableBeanFactory getBeanFactory() throws IllegalStateException { return null; }}

回歸正題,Spring容器在初始化的時候都會執(zhí)行一個方法來結(jié)束初始化,那就是refresh()方法,此方法定義在接口ConfigurableApplicationContext中,并且抽象類AbstractApplicationContext實現(xiàn)了它,代碼如下

@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 為容器的刷新做準備工作,設(shè)置啟動日期,更新活動標志,加載屬性資源 prepareRefresh(); // 獲取最新的bean工廠對象。 // 要求子類刷新自身持有的bean工廠對象 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 在容器使用bean工廠之前,設(shè)置bean工廠 // 主要是添加特定的bean后處理器 prepareBeanFactory(beanFactory); try { // 鉤子方法,允許在子類中bean工廠做進一步的處理 // 子類可以根據(jù)自身需要,添加更多的bean后處理器 postProcessBeanFactory(beanFactory); // 在上下文容器中執(zhí)行所有注冊了的bean工廠后處理器 // 執(zhí)行步驟:1. 在bean工廠中找到所有實現(xiàn)了BeanFactoryPostProcessor的對象 // ->2. 執(zhí)行所有bean工廠后處理器的postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(beanFactory); // 把所有用戶配置的bean后處理器添加到bean工廠中 registerBeanPostProcessors(beanFactory); // 初始化國際化消息對象,默認為DelegatingMessageSource initMessageSource(); // 初始化事件傳播器,默認為SimpleApplicationEventMulticaster initApplicationEventMulticaster(); // 鉤子方法,初始化其他特定的bean onRefresh(); // 注冊用戶指定的和容器創(chuàng)建時添加的監(jiān)聽器 registerListeners(); // 初始化所有剩下的單例非延遲bean finishBeanFactoryInitialization(beanFactory); // 完成刷新,包括發(fā)布容器刷新事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } /// 銷毀所有已經(jīng)創(chuàng)建好的bean,以防止內(nèi)存浪費 destroyBeans(); // 重置活動標志 cancelRefresh(ex); throw ex; } finally { // 重置反射緩存 resetCommonCaches(); } } }

refresh方法的設(shè)計使用了模板方法設(shè)計模式,它設(shè)定了容器刷新的流程,并把特定階段的執(zhí)行延遲到子類中執(zhí)行,比如bean工廠的創(chuàng)建。它還在特定的階段提供鉤子方法,以方便子類根據(jù)自身需要進一步完成更多的操作。下面我們一步一步的探討refresh方法的執(zhí)行流程。下圖是它的一個大概流程圖。

refresh方法在容器的基本配置完成后被調(diào)用,它是spring容器初始化過程的主要戰(zhàn)場,下面我們一步一步的探討refresh方法的執(zhí)行流程。

容器刷新過程


1. 容器刷新前準備

在refresh方法的第1步中,調(diào)用AbstractApplicationContext的prepareRefresh()方法完成容器刷新前的準備,代碼如下。

protected void prepareRefresh() { // 設(shè)置啟動時間 this.startupDate = System.currentTimeMillis(); this.closed.set(false); // 把容器設(shè)置為活動 this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // 鉤子方法,讓子類把所有的stub屬性資源替換成真正需要的屬性資源。 initPropertySources(); // 驗證所有被標注為required的屬性是否可被解析 getEnvironment().validateRequiredProperties(); // 允許事件傳播器可用的時候發(fā)布一些事件 // earlyApplicationEvents存儲需要在事件傳播器可用時發(fā)布的事件 this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }

prepareRefresh方法設(shè)置容器啟動時間和活動標志,以及通過調(diào)用initPropertySources()方法完成所有的property資源的初始化。initPropertySources()方法是一個空實現(xiàn),子類可以用它來完成property資源的初始化。例如,下面代碼是在AbstractRefreshableWebApplicationContext類中的實現(xiàn)

@Override protected void initPropertySources() { super.initPropertySources(); ConfigurableEnvironment env = this.getEnvironment(); if (env instanceof ConfigurableWebEnvironment) { ((ConfigurableWebEnvironment)env).initPropertySources( this.servletContext, this.servletConfig); } }

這個方法主要是把ServletContext和ServletConfig對象保存到ConfigurableWebEnvironment環(huán)境對象中,以方便環(huán)境對象通過getProperty(String key)方法獲取定義在ServletContext和ServletConfig中特定的初始化init-param參數(shù)。

2. 創(chuàng)建BeanFactory

執(zhí)行AbstractApplicationContext的obtainFreshBeanFactory方法,獲取最新的bean工廠對象,代碼如下。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 刷新bean工廠,是一個抽象方法,由子類實現(xiàn)。 refreshBeanFactory(); // 從子類中獲取bean工廠,也是一個抽象方法,由子類實現(xiàn) ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }

obtainFreshBeanFactory方法首先調(diào)用子類的refreshBeanFactory()方法刷新bean工廠,然后調(diào)用子類的getBeanFactory()方法獲取bean工廠。在spring中,refreshBeanFactory()在GenericApplicationContext類和AbstractRefreshableApplicationContext類中都有實現(xiàn),下面是在AbstractRefreshableApplicationContext類中的實現(xiàn)。

@Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { // 如果當前上線文容器已有bean工廠 // 銷毀bean工廠中所有單例bean destroyBeans(); // 關(guān)閉已有的bean工廠 closeBeanFactory(); } try { // 創(chuàng)建一個新的bean工廠 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // 自定義bean工廠,包括設(shè)置是否允許覆蓋相同ID的bean,是否允許循環(huán)引用,等等 customizeBeanFactory(beanFactory); // 加載所有BeanDefinition,是一個抽象方法,有子類實現(xiàn) loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }

這個方法里面,首先把已創(chuàng)建的單例bean銷毀并關(guān)閉持有的bean工廠,然后調(diào)用createBeanFactory()方法重新創(chuàng)建一個x新的bean工廠代碼如下。最后,并調(diào)用子類的loadBeanDefinitions方法把BeanDefinition對象加載到bean工廠中。

/** * 創(chuàng)建一個新的bean工廠 **/ protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); }

3. 初始化BeanFactory

獲取到BeanFactory對象后,refresh()方法調(diào)用AbstractApplicationContext對象的prepareBeanFactory方法和postProcessBeanFactory方法完成bean工廠的初始化。在這個階段,容器中所有的BeanDefinition對象已經(jīng)被注冊到bean工廠中(除被@Configuration注解的類管理的bean配置外),但是沒有任何一個BeanDefinition所代表的bean被創(chuàng)建,包括工廠后處理器。下面我們看看這個兩個方法的執(zhí)行情況。

首先,調(diào)用prepareBeanFactory方法。這個方法主要功能是,為bean工廠設(shè)置容器的類加載器,以及一些特定的bean后處理器,代碼如下。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 要求bean工廠和容器共用同一個類加載器 beanFactory.setBeanClassLoader(getClassLoader()); // 設(shè)置SpEL表達式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); // 添加Resource編輯器注冊器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加ApplicationContextAwareProcessor后處理器 // 有可能某些工廠后處理器實現(xiàn)了ApplicationContextAware、ResourceLoaderAware等等如下類似接口 // ApplicationContextAwareProcessor后處理器就就為這些接口傳遞相應(yīng)的對象 // 因此,在執(zhí)行工廠后處理器前,必須要設(shè)置此后處理器 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Detect a LoadTimeWeaver and prepare for weaving, if found. // 檢測用戶是否配置了loadTimeWeaver bean對象 if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { // 添加LoadTimeWeaverAwareProcessor后處理器,此后處理器用于向bean中注入LoadTimeWeaver對象 beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // 為類型匹配檢測配置臨時的類加載器 beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } // 注冊默認的環(huán)境bean對象 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } // 注冊O(shè)S系統(tǒng)屬性對象 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } // 注冊O(shè)S系統(tǒng)環(huán)境對象 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }

然后,調(diào)用postProcessBeanFactory方法。這個方法在AbstractApplicationContext類中的定義如下。

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }

postProcessBeanFactory方法被作為鉤子方法,讓子類在bean工廠初始化的時候根據(jù)自身需要,對bean工廠做更多的操作。在web應(yīng)用中,AbstractRefreshableWebApplicationContext類重寫此方法,代碼如下。

/** * 注冊request/session作用域, 和ServletContextAwareProcessor bean后處理器, . */ @Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 添加ServletContextAwareProcessor后處理器 beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); beanFactory.ignoreDependencyInterface(ServletContextAware.class); beanFactory.ignoreDependencyInterface(ServletConfigAware.class); // 注冊request/session作用域 WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); // 把ServletContext對象和ServletConfig對象等以單例bean的形式注冊到bean工廠中 WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); }

4. 執(zhí)行bean工廠后處理器的postProcessBeanFactory方法

bean工廠初始化完成后,refresh()方法調(diào)用AbstractApplicationContext的invokeBeanFactoryPostProcessors方法完成容器中所有bean工廠后處理器的執(zhí)行,代碼如下。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 把執(zhí)行工廠后處理器的任務(wù)委托給PostProcessorRegistrationDelegate PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); // 檢測LoadTimeWeaver對象 // 聲明:String LOAD_TIME_WEAVER_BEAN_NAME = "loadTimeWeaver"; if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }

這段代碼主要是把工廠后處理器的任務(wù)委托給PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法,此方法的代碼如下。

public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 首先執(zhí)行BeanDefinitionRegistryPostProcessors Set<String> processedBeans = new HashSet<String>(); if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new LinkedList<BeanFactoryPostProcessor>(); List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new LinkedList<BeanDefinitionRegistryPostProcessor>(); // 遍歷容器中的工廠后處理器,并執(zhí)行BeanDefinitionRegistryPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 執(zhí)行BeanDefinitionRegistryPostProcessors的 // ->postProcessBeanDefinitionRegistry方法 registryPostProcessor.postProcessBeanDefinitionRegistry(registry); registryPostProcessors.add(registryPostProcessor); } else { regularPostProcessors.add(postProcessor); } } // 獲取bean工廠中定義的BeanDefinitionRegistryPostProcessor對象 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 首先,執(zhí)行實現(xiàn)了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor對象 List<BeanDefinitionRegistryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(beanFactory, priorityOrderedPostProcessors); registryPostProcessors.addAll(priorityOrderedPostProcessors); invokeBeanDefinitionRegistryPostProcessors(priorityOrderedPostProcessors, registry); // 然后,執(zhí)行實現(xiàn)了Ordered接口的BeanDefinitionRegistryPostProcessor對象 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); List<BeanDefinitionRegistryPostProcessor> orderedPostProcessors = new ArrayList<BeanDefinitionRegistryPostProcessor>(); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } sortPostProcessors(beanFactory, orderedPostProcessors); registryPostProcessors.addAll(orderedPostProcessors); invokeBeanDefinitionRegistryPostProcessors(orderedPostProcessors, registry); // 最后執(zhí)行其它的BeanDefinitionRegistryPostProcessor對象 boolean reiterate = true; while (reiterate) { reiterate = false; postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { if (!processedBeans.contains(ppName)) { BeanDefinitionRegistryPostProcessor pp = beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class); registryPostProcessors.add(pp); processedBeans.add(ppName); pp.postProcessBeanDefinitionRegistry(registry); reiterate = true; } } } // 執(zhí)行BeanDefinitionRegistryPostProcessor工廠后處理器 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); // 執(zhí)行容器中普通的工廠后處理器 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // 執(zhí)行容器中的bean工廠后處理器 invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // 獲取定義在bean工廠中的bean工廠后處理器 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // 把bean工廠后處理器按PriorityOrdered、Ordered和其他來分類 List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // 排除前面已經(jīng)執(zhí)行了的后處理器 } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } else { nonOrderedPostProcessorNames.add(ppName); } } // 首先執(zhí)行實現(xiàn)了PriorityOrdered接口的后處理器 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 然后執(zhí)行實現(xiàn)了Ordered接口的后處理器 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(beanFactory, orderedPostProcessors); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 最后執(zhí)行其他的后處理器 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 清除工廠中的元數(shù)據(jù)緩存 beanFactory.clearMetadataCache(); } /** * 執(zhí)行給定的BeanDefinitionRegistryPostProcessor beans. */ private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } } /** * 執(zhí)行給定的bean工廠 **/ private static void invokeBeanFactoryPostProcessors( Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) { for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } }

上面的執(zhí)行流程用圖表達如下。 這里寫圖片描述

上圖很明顯的表達了bean工廠后處理器的執(zhí)行順序,但這里還有兩點需要說明的。

a. 為什么要先執(zhí)行BeanDefinitionRegistryPostProcessor?因為實現(xiàn)BeanDefinitionRegistryPostProcessor 接口的后處理器可以在bean工廠創(chuàng)建其他bean之前添加更多的BeanDefinition對象到bean工廠中去。比如spring中ConfigurationClassPostProcessor類就是這樣一種工廠后處理器,它主要把被@Configuration注解的類中定義的bean信息轉(zhuǎn)換成BeanDefinition對象,并注冊到bean工廠中。

b. 這個流程中有一個很明顯的規(guī)定就是,不管是什么工廠后處理器,都必須先執(zhí)行容器中的工廠后處理器后,才執(zhí)行bean工廠中的工廠后處理器。

5. 注冊BeanPostProcessor

refresh()方法執(zhí)行完bean工廠后處理器后,接著調(diào)用AbstractApplicationContext的registerBeanPostProcessors方法向bean工廠注冊bean后處理器,registerBeanPostProcessors方法的代碼如下。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 把注冊bean后處理器的任務(wù)委托給PostProcessorRegistrationDelegate PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }

registerBeanPostProcessors方法把注冊bean后處理器的任務(wù)委托給PostProcessorRegistrationDelegate類的registerBeanPostProcessors方法,下面是這個方法的代碼。

public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { // 從bean工廠中找到所有BeanPostProcessor對象的名稱 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // 注冊BeanPostProcessorChecker后處理器 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // 對所有的bean后處理器根據(jù)實現(xiàn)PriorityOrdered,Ordered和其他的進行分組 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); List<BeanPostProcessor> internalPostProcessors = new ArrayList<BeanPostProcessor>(); List<String> orderedPostProcessorNames = new ArrayList<String>(); List<String> nonOrderedPostProcessorNames = new ArrayList<String>(); 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); } } // 首先注冊實現(xiàn)了PriorityOrdered接口的bean后處理器 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 然后注冊實現(xiàn)了Ordered接口的后處理器. List<BeanPostProcessor> orderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : orderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } sortPostProcessors(beanFactory, orderedPostProcessors); registerBeanPostProcessors(beanFactory, orderedPostProcessors); // 再次,注冊所有普通的后處理器 List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanPostProcessor>(); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // 最后,重新注冊所有內(nèi)部后處理器 // ->即實現(xiàn)了MergedBeanDefinitionPostProcessor接口的后處理器 sortPostProcessors(beanFactory, internalPostProcessors); registerBeanPostProcessors(beanFactory, internalPostProcessors); beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); } /** * 注冊指定的BeanPostProcessor beans. */ private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) { for (BeanPostProcessor postProcessor : postProcessors) { beanFactory.addBeanPostProcessor(postProcessor); } }

這部分代碼注冊bean后處理器的注冊流程如下。

這里寫圖片描述

整個流程根據(jù)PriorityOrdered、Ordered、非Ordered的順序注冊bean后處理器,最后注冊MergedBeanDefinitionPostProcessor bean后處理器。其中MergedBeanDefinitionPostProcessor會在其他bean后處理器執(zhí)行前執(zhí)行它的postProcessMergedBeanDefinition方法。

6. 初始化MessageSource國際化消息

執(zhí)行AbstractApplicationContext的initMessageSource方法,代碼如下

protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 聲明:public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource"; // 檢測用戶是否指定了messageSource if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // 使當前messageSource能夠使用父容器中的messageSource if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) { HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource; if (hms.getParentMessageSource() == null) { hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isDebugEnabled()) { logger.debug("Using MessageSource [" + this.messageSource + "]"); } } else { // 用戶沒有指定messageSource // 使用一個空的MessageSource,以能夠接受getMessage方法的調(diào)用 DelegatingMessageSource dms = new DelegatingMessageSource(); dms.setParentMessageSource(getInternalParentMessageSource()); this.messageSource = dms; beanFactory.registerSingleton(MESSAGE_SOURCE_BEAN_NAME, this.messageSource); if (logger.isDebugEnabled()) { logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME + "': using default [" + this.messageSource + "]"); } } }

注意:如果要使用國際化消息,必須提供bean名稱為messageSource的MessageSource對象,形如下面的配置。

<bean id="messageSource" class="org.springframework.context.support.ReloadableResourceBundleMessageSource"> <property name="basenames"> <list> <value>/WEB-INF/languages/globe/messages</value> </list> </property> <property name="cacheSeconds" value="1800"/> <property name="defaultEncoding" value="UTF-8"/> </bean>

7. 初始化事件傳播器

refresh()方法完成國際化消息對象初始化后,接著調(diào)用AbstractApplicationContext的initApplicationEventMulticaster方法為容器添加事件傳播器,代碼如下。

protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 聲明:public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster"; // 檢測用戶是否制定了事件傳播器 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); if (logger.isDebugEnabled()) { logger.debug("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]"); } } else { // 使用默認的事件傳播器 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); if (logger.isDebugEnabled()) { logger.debug("Unable to locate ApplicationEventMulticaster with name '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "': using default [" + this.applicationEventMulticaster + "]"); } } }

8. 其他初始化

refresh()方法完成國際化消息和事件傳播器的初始化后,把容器的初始化交給onRefresh()方法,代碼如下。

protected void onRefresh() throws BeansException { // For subclasses: do nothing by default. }

onRefresh()方法被設(shè)計成容器初始化的鉤子,以方便子類初始化其他特定的bean。例如,下面是在AbstractRefreshableWebApplicationContext類中onRefresh()方法被重寫的代碼。

/** * Initialize the theme capability. */ @Override protected void onRefresh() { this.themeSource = UiApplicationContextUtils.initThemeSource(this); }

其中,UiApplicationContextUtils工具類的initThemeSource(ApplicationContext context)方法的代碼如下。

public static ThemeSource initThemeSource(ApplicationContext context) { // 聲明有:public static final String THEME_SOURCE_BEAN_NAME = "themeSource"; if (context.containsLocalBean(THEME_SOURCE_BEAN_NAME)) { ThemeSource themeSource = context.getBean(THEME_SOURCE_BEAN_NAME, ThemeSource.class); // 使themeSource關(guān)聯(lián)父容器,這個父容器必須實現(xiàn)了ThemeSource接口 if (context.getParent() instanceof ThemeSource && themeSource instanceof HierarchicalThemeSource) { HierarchicalThemeSource hts = (HierarchicalThemeSource) themeSource; if (hts.getParentThemeSource() == null) { hts.setParentThemeSource((ThemeSource) context.getParent()); } } if (logger.isDebugEnabled()) { logger.debug("Using ThemeSource [" + themeSource + "]"); } return themeSource; } else { HierarchicalThemeSource themeSource = null; if (context.getParent() instanceof ThemeSource) { // 把對ThemeSource的操作代理給父容器 themeSource = new DelegatingThemeSource(); themeSource.setParentThemeSource((ThemeSource) context.getParent()); } else { // 使用默認的ThemeSource themeSource = new ResourceBundleThemeSource(); } if (logger.isDebugEnabled()) { logger.debug("Unable to locate ThemeSource with name '" + THEME_SOURCE_BEAN_NAME + "': using default [" + themeSource + "]"); } return themeSource; } }

9. 注冊監(jiān)聽器

執(zhí)行完成子類實現(xiàn)的onRefresh()方法,需要向容器中注冊各種監(jiān)聽器,此時執(zhí)行AbstractApplicationContext的registerListeners()方法,這個方法的代碼如下。

protected void registerListeners() { // 首先注冊容器中特定的事件監(jiān)聽器 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 找到用戶配置的所有的監(jiān)聽器bean名稱 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { // 在事件傳播器中只保存監(jiān)聽器的bean名稱 // 這里不實例化監(jiān)聽器的原因是為了讓后處理器在它們真正實例化的時候作用于它們 getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 發(fā)布那些需要提前發(fā)布的事件 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }

10. 實例化非延遲單例bean

前面所有的初始化操作都完成了后,則開始實例化剩下的單例非延遲加載的bean。通過執(zhí)行AbstractApplicationContext的finishBeanFactoryInitialization方法完成,這個方法的代碼如下。

protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 初始化ConversionService // 在ConfigurableApplicationContext接口中聲明:String CONVERSION_SERVICE_BEAN_NAME = "conversionService"; 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)); } // 注冊一個默認的內(nèi)部value解析器 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(new StringValueResolver() { @Override public String resolveStringValue(String strVal) { return getEnvironment().resolvePlaceholders(strVal); } }); } // 初始化LoadTimeWeaverAware對象來支持注冊他們的transformers String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // 停止使用臨時類加載器來做類型匹配 beanFactory.setTempClassLoader(null); // 允許緩存所有的bean元數(shù)據(jù)定義,不希望今后再更改 beanFactory.freezeConfiguration(); // 初始化所有非延遲單例bean beanFactory.preInstantiateSingletons(); }

11. 完成刷新

refresh()方法的最后一步,AbstractApplicationContext的finishRefresh方法,完成容器刷新,執(zhí)行LifecycleProcessor對象的onRefresh方法,以及發(fā)布刷新事件。代碼如下,

protected void finishRefresh() { // 初始化生命周期處理器,默認為DefaultLifecycleProcessor initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. // 首先把刷新操作傳遞給生命周期處理器 getLifecycleProcessor().onRefresh(); // 最后發(fā)布容器刷新事件 publishEvent(new ContextRefreshedEvent(this)); // 把spring容器加入到LiveBeansView的MBeanServer中 LiveBeansView.registerApplicationContext(this); } /** * 初始化生命周期處理器 **/ protected void initLifecycleProcessor() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 聲明:public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor"; if (beanFactory.containsLocalBean(LIFECYCLE_PROCESSOR_BEAN_NAME)) { // 使用用戶指定的生命周期處理器 this.lifecycleProcessor = beanFactory.getBean(LIFECYCLE_PROCESSOR_BEAN_NAME, LifecycleProcessor.class); if (logger.isDebugEnabled()) { logger.debug("Using LifecycleProcessor [" + this.lifecycleProcessor + "]"); } } else { // 使用默認的聲明周期處理器 DefaultLifecycleProcessor defaultProcessor = new DefaultLifecycleProcessor(); defaultProcessor.setBeanFactory(beanFactory); this.lifecycleProcessor = defaultProcessor; beanFactory.registerSingleton(LIFECYCLE_PROCESSOR_BEAN_NAME, this.lifecycleProcessor); if (logger.isDebugEnabled()) { logger.debug("Unable to locate LifecycleProcessor with name '" + LIFECYCLE_PROCESSOR_BEAN_NAME + "': using default [" + this.lifecycleProcessor + "]"); } } }

到這里spring的刷新也就完成了。

總結(jié)


(1)spring的所有容器都直接或間接繼承了抽象類AbstractApplicationContext。

(2) spring的容器在創(chuàng)建并完成基本的配置后,在初次使用前,還必須執(zhí)行refresh()方法。

(3)實現(xiàn)BeanDefinitionRegistryPostProcessor 接口的后處理器可以在bean工廠創(chuàng)建其他bean之前添加更多的BeanDefinition對象到bean工廠中去。比如spring中ConfigurationClassPostProcessor類,它主要把被@Configuration注解的類中定義的bean信息轉(zhuǎn)換成BeanDefinition對象,并注冊到bean工廠中。

(4)可以自定義BeanPostProcessor工廠后處理器對BeanDefinition對象做處理,比如spring的PreferencesPlaceholderConfigurer工廠后處理器,它把屬性文件中的值與BeanDefinition中相應(yīng)的屬性值相替換。

(5)指定國際化消息時,MessageSource對象的bean名稱必須為messageSource。

(6)容器刷新過程中的鉤子方法有: a. initPropertySources()由子類根據(jù)自身的應(yīng)用環(huán)境初始化property資源。 b. postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)用于在bean工廠后處理器執(zhí)行前由子類對bean工廠做更多的初始化操作。 c. onRefresh()用于初始化子類中特定的bean。

(7)LiveBeansView的使用

Spring容器初始化過程中的最后一步,把spring容器加入到LiveBeansView的MBeanServer中。這個LiveBeansView它是一個MBean對象,它的作用是查看當前活動的bean以及這些bean的依賴。下面步驟介紹如何使用它。

a. 在web.xml文件配置如下,其中param-value可以任意取

<context-param> <param-name>spring.liveBeansView.mbeanDomain</param-name> <param-value>chyohn_liveBeansView</param-value> </context-param>

b. 啟動應(yīng)用后,打開%java_HOME%/bin/jconsole.exe程序,如下

這里寫圖片描述

c. 我使用的tomcat服務(wù)器啟動的,點擊第2個鏈接,進入的頁面,如下

這里寫圖片描述

上面的JSON數(shù)據(jù)中就包含當前spring容器中所有的bean,是不是很神奇?這也是java MBean的一個例子。


發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 欧美日韩在线中文字幕 | 亚洲情视频| 91精品国产日韩91久久久久久360 | 在线影院av | 欧美激情性色生活片在线观看 | 欧美国产一区二区三区 | 亚洲精品久久久久久久久久久 | 国产日产精品一区二区三区四区 | 欧美在线中文字幕 | 欧美特黄a | 国产成人自拍av | 国产porn在线 | 免费午夜视频在线观看 | 黄色影院| 欧美成人一区免费视频 | 亚州综合网 | 亚洲国产资源 | 欧美精品免费一区二区三区 | 亚洲精品成人久久 | 性大片免费看 | 亚久久| 欧美成在线视频 | 国产深夜福利视频在线播放 | 黄色免费入口 | 亚州欧美在线 | 欧美三级一级 | 韩国精品一区二区三区四区五区 | av手机在线电影 | 99久久婷婷国产综合精品青牛牛 | 久久久久9999 | 在线a| 色999国产| 欧美18—19sex性hd按摩 | 亚洲生活片 | 亚洲网在线观看 | 日本精品视频一区二区三区四区 | 久久久综合久久久 | 国产精彩视频在线 | 久久久久97国产精 | 久热久操 | 羞羞视频在线免费 |