首页 > 学院 > 开发设计 > 正文

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

2019-11-10 19:44:55
字体:
来源:转载
供稿:网友

概述


SPRing容器体系的继承结构图如下。

这里写图片描述

从图中可以看出抽象类AbstractapplicationContext是所有容器类的父类。AbstractApplicationContext实现了它继承的所有接口方法,并定义了三个用于管理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;

小技巧:告诉大家如何查看一个抽象类未实现的接口方法有哪些,比如上面的AbstractApplicationContext抽象类。我创建了一个MyApplicationContext 类,如果未实现任何方法,IDE会提醒我实现父类中未实现的方法,代码如下。

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容器在初始化的时候都会执行一个方法来结束初始化,那就是refresh()方法,此方法定义在接口ConfigurableApplicationContext中,并且抽象类AbstractApplicationContext实现了它,代码如下

@Override public void refresh() throws BeansException, IllegalStateException { synchronized (this.startupShutdownMonitor) { // 为容器的刷新做准备工作,设置启动日期,更新活动标志,加载属性资源 prepareRefresh(); // 获取最新的bean工厂对象。 // 要求子类刷新自身持有的bean工厂对象 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 在容器使用bean工厂之前,设置bean工厂 // 主要是添加特定的bean后处理器 prepareBeanFactory(beanFactory); try { // 钩子方法,允许在子类中bean工厂做进一步的处理 // 子类可以根据自身需要,添加更多的bean后处理器 postProcessBeanFactory(beanFactory); // 在上下文容器中执行所有注册了的bean工厂后处理器 // 执行步骤:1. 在bean工厂中找到所有实现了BeanFactoryPostProcessor的对象 // ->2. 执行所有bean工厂后处理器的postProcessBeanFactory方法 invokeBeanFactoryPostProcessors(beanFactory); // 把所有用户配置的bean后处理器添加到bean工厂中 registerBeanPostProcessors(beanFactory); // 初始化国际化消息对象,默认为DelegatingMessageSource initMessageSource(); // 初始化事件传播器,默认为SimpleApplicationEventMulticaster initApplicationEventMulticaster(); // 钩子方法,初始化其他特定的bean onRefresh(); // 注册用户指定的和容器创建时添加的监听器 registerListeners(); // 初始化所有剩下的单例非延迟bean finishBeanFactoryInitialization(beanFactory); // 完成刷新,包括发布容器刷新事件 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } /// 销毁所有已经创建好的bean,以防止内存浪费 destroyBeans(); // 重置活动标志 cancelRefresh(ex); throw ex; } finally { // 重置反射缓存 resetCommonCaches(); } } }

refresh方法的设计使用了模板方法设计模式,它设定了容器刷新的流程,并把特定阶段的执行延迟到子类中执行,比如bean工厂的创建。它还在特定的阶段提供钩子方法,以方便子类根据自身需要进一步完成更多的操作。下面我们一步一步的探讨refresh方法的执行流程。下图是它的一个大概流程图。

refresh方法在容器的基本配置完成后被调用,它是spring容器初始化过程的主要战场,下面我们一步一步的探讨refresh方法的执行流程。

容器刷新过程


1. 容器刷新前准备

在refresh方法的第1步中,调用AbstractApplicationContext的prepareRefresh()方法完成容器刷新前的准备,代码如下。

protected void prepareRefresh() { // 设置启动时间 this.startupDate = System.currentTimeMillis(); this.closed.set(false); // 把容器设置为活动 this.active.set(true); if (logger.isInfoEnabled()) { logger.info("Refreshing " + this); } // 钩子方法,让子类把所有的stub属性资源替换成真正需要的属性资源。 initPropertySources(); // 验证所有被标注为required的属性是否可被解析 getEnvironment().validateRequiredProperties(); // 允许事件传播器可用的时候发布一些事件 // earlyApplicationEvents存储需要在事件传播器可用时发布的事件 this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>(); }

prepareRefresh方法设置容器启动时间和活动标志,以及通过调用initPropertySources()方法完成所有的property资源的初始化。initPropertySources()方法是一个空实现,子类可以用它来完成property资源的初始化。例如,下面代码是在AbstractRefreshableWebApplicationContext类中的实现

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

这个方法主要是把ServletContext和ServletConfig对象保存到ConfigurableWebEnvironment环境对象中,以方便环境对象通过getProperty(String key)方法获取定义在ServletContext和ServletConfig中特定的初始化init-param参数。

2. 创建BeanFactory

执行AbstractApplicationContext的obtainFreshBeanFactory方法,获取最新的bean工厂对象,代码如下。

protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { // 刷新bean工厂,是一个抽象方法,由子类实现。 refreshBeanFactory(); // 从子类中获取bean工厂,也是一个抽象方法,由子类实现 ConfigurableListableBeanFactory beanFactory = getBeanFactory(); if (logger.isDebugEnabled()) { logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory); } return beanFactory; }

obtainFreshBeanFactory方法首先调用子类的refreshBeanFactory()方法刷新bean工厂,然后调用子类的getBeanFactory()方法获取bean工厂。在spring中,refreshBeanFactory()在GenericApplicationContext类和AbstractRefreshableApplicationContext类中都有实现,下面是在AbstractRefreshableApplicationContext类中的实现。

@Override protected final void refreshBeanFactory() throws BeansException { if (hasBeanFactory()) { // 如果当前上线文容器已有bean工厂 // 销毁bean工厂中所有单例bean destroyBeans(); // 关闭已有的bean工厂 closeBeanFactory(); } try { // 创建一个新的bean工厂 DefaultListableBeanFactory beanFactory = createBeanFactory(); beanFactory.setSerializationId(getId()); // 自定义bean工厂,包括设置是否允许覆盖相同ID的bean,是否允许循环引用,等等 customizeBeanFactory(beanFactory); // 加载所有BeanDefinition,是一个抽象方法,有子类实现 loadBeanDefinitions(beanFactory); synchronized (this.beanFactoryMonitor) { this.beanFactory = beanFactory; } } catch (IOException ex) { throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex); } }

这个方法里面,首先把已创建的单例bean销毁并关闭持有的bean工厂,然后调用createBeanFactory()方法重新创建一个x新的bean工厂代码如下。最后,并调用子类的loadBeanDefinitions方法把BeanDefinition对象加载到bean工厂中。

/** * 创建一个新的bean工厂 **/ protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); }

3. 初始化BeanFactory

获取到BeanFactory对象后,refresh()方法调用AbstractApplicationContext对象的prepareBeanFactory方法和postProcessBeanFactory方法完成bean工厂的初始化。在这个阶段,容器中所有的BeanDefinition对象已经被注册到bean工厂中(除被@Configuration注解的类管理的bean配置外),但是没有任何一个BeanDefinition所代表的bean被创建,包括工厂后处理器。下面我们看看这个两个方法的执行情况。

首先,调用prepareBeanFactory方法。这个方法主要功能是,为bean工厂设置容器的类加载器,以及一些特定的bean后处理器,代码如下。

protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 要求bean工厂和容器共用同一个类加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 设置SpEL表达式解析器 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver()); // 添加Resource编辑器注册器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); // 添加ApplicationContextAwareProcessor后处理器 // 有可能某些工厂后处理器实现了ApplicationContextAware、ResourceLoaderAware等等如下类似接口 // ApplicationContextAwareProcessor后处理器就就为这些接口传递相应的对象 // 因此,在执行工厂后处理器前,必须要设置此后处理器 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())); } // 注册默认的环境bean对象 if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment()); } // 注册OS系统属性对象 if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties()); } // 注册OS系统环境对象 if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) { beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment()); } }

然后,调用postProcessBeanFactory方法。这个方法在AbstractApplicationContext类中的定义如下。

protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { }

postProcessBeanFactory方法被作为钩子方法,让子类在bean工厂初始化的时候根据自身需要,对bean工厂做更多的操作。在web应用中,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. 执行bean工厂后处理器的postProcessBeanFactory方法

bean工厂初始化完成后,refresh()方法调用AbstractApplicationContext的invokeBeanFactoryPostProcessors方法完成容器中所有bean工厂后处理器的执行,代码如下。

protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 把执行工厂后处理器的任务委托给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())); } }

这段代码主要是把工厂后处理器的任务委托给PostProcessorRegistrationDelegate的invokeBeanFactoryPostProcessors方法,此方法的代码如下。

public static void invokeBeanFactoryPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // 首先执行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>(); // 遍历容器中的工厂后处理器,并执行BeanDefinitionRegistryPostProcessors for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryPostProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 执行BeanDefinitionRegistryPostProcessors的 // ->postProcessBeanDefinitionRegistry方法 registryPostProcessor.postProcessBeanDefinitionRegistry(registry); registryPostProcessors.add(registryPostProcessor); } else { regularPostProcessors.add(postProcessor); } } // 获取bean工厂中定义的BeanDefinitionRegistryPostProcessor对象 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); // 首先,执行实现了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); // 然后,执行实现了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); // 最后执行其它的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; } } } // 执行BeanDefinitionRegistryPostProcessor工厂后处理器 invokeBeanFactoryPostProcessors(registryPostProcessors, beanFactory); // 执行容器中普通的工厂后处理器 invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } else { // 执行容器中的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)) { // 排除前面已经执行了的后处理器 } 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); } } // 首先执行实现了PriorityOrdered接口的后处理器 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // 然后执行实现了Ordered接口的后处理器 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } sortPostProcessors(beanFactory, orderedPostProcessors); invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // 最后执行其他的后处理器 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<BeanFactoryPostProcessor>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // 清除工厂中的元数据缓存 beanFactory.clearMetadataCache(); } /** * 执行给定的BeanDefinitionRegistryPostProcessor beans. */ private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } } /** * 执行给定的bean工厂 **/ private static void invokeBeanFactoryPostProcessors( Collection<? extends BeanFactoryPostProcessor> postProcessors, ConfigurableListableBeanFactory beanFactory) { for (BeanFactoryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanFactory(beanFactory); } }

上面的执行流程用图表达如下。 这里写图片描述

上图很明显的表达了bean工厂后处理器的执行顺序,但这里还有两点需要说明的。

a. 为什么要先执行BeanDefinitionRegistryPostProcessor?因为实现BeanDefinitionRegistryPostProcessor 接口的后处理器可以在bean工厂创建其他bean之前添加更多的BeanDefinition对象到bean工厂中去。比如spring中ConfigurationClassPostProcessor类就是这样一种工厂后处理器,它主要把被@Configuration注解的类中定义的bean信息转换成BeanDefinition对象,并注册到bean工厂中。

b. 这个流程中有一个很明显的规定就是,不管是什么工厂后处理器,都必须先执行容器中的工厂后处理器后,才执行bean工厂中的工厂后处理器。

5. 注册BeanPostProcessor

refresh()方法执行完bean工厂后处理器后,接着调用AbstractApplicationContext的registerBeanPostProcessors方法向bean工厂注册bean后处理器,registerBeanPostProcessors方法的代码如下。

protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 把注册bean后处理器的任务委托给PostProcessorRegistrationDelegate PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }

registerBeanPostProcessors方法把注册bean后处理器的任务委托给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后处理器根据实现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); } } // 首先注册实现了PriorityOrdered接口的bean后处理器 sortPostProcessors(beanFactory, priorityOrderedPostProcessors); registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // 然后注册实现了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); // 最后,重新注册所有内部后处理器 // ->即实现了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后处理器的注册流程如下。

这里写图片描述

整个流程根据PriorityOrdered、Ordered、非Ordered的顺序注册bean后处理器,最后注册MergedBeanDefinitionPostProcessor bean后处理器。其中MergedBeanDefinitionPostProcessor会在其他bean后处理器执行前执行它的postProcessMergedBeanDefinition方法。

6. 初始化MessageSource国际化消息

执行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方法的调用 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()方法完成国际化消息对象初始化后,接着调用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()方法被设计成容器初始化的钩子,以方便子类初始化其他特定的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关联父容器,这个父容器必须实现了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. 注册监听器

执行完成子类实现的onRefresh()方法,需要向容器中注册各种监听器,此时执行AbstractApplicationContext的registerListeners()方法,这个方法的代码如下。

protected void registerListeners() { // 首先注册容器中特定的事件监听器 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 找到用户配置的所有的监听器bean名称 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { // 在事件传播器中只保存监听器的bean名称 // 这里不实例化监听器的原因是为了让后处理器在它们真正实例化的时候作用于它们 getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // 发布那些需要提前发布的事件 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }

10. 实例化非延迟单例bean

前面所有的初始化操作都完成了后,则开始实例化剩下的单例非延迟加载的bean。通过执行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)); } // 注册一个默认的内部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元数据定义,不希望今后再更改 beanFactory.freezeConfiguration(); // 初始化所有非延迟单例bean beanFactory.preInstantiateSingletons(); }

11. 完成刷新

refresh()方法的最后一步,AbstractApplicationContext的finishRefresh方法,完成容器刷新,执行LifecycleProcessor对象的onRefresh方法,以及发布刷新事件。代码如下,

protected void finishRefresh() { // 初始化生命周期处理器,默认为DefaultLifecycleProcessor initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. // 首先把刷新操作传递给生命周期处理器 getLifecycleProcessor().onRefresh(); // 最后发布容器刷新事件 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的刷新也就完成了。

总结


(1)spring的所有容器都直接或间接继承了抽象类AbstractApplicationContext。

(2) spring的容器在创建并完成基本的配置后,在初次使用前,还必须执行refresh()方法。

(3)实现BeanDefinitionRegistryPostProcessor 接口的后处理器可以在bean工厂创建其他bean之前添加更多的BeanDefinition对象到bean工厂中去。比如spring中ConfigurationClassPostProcessor类,它主要把被@Configuration注解的类中定义的bean信息转换成BeanDefinition对象,并注册到bean工厂中。

(4)可以自定义BeanPostProcessor工厂后处理器对BeanDefinition对象做处理,比如spring的PreferencesPlaceholderConfigurer工厂后处理器,它把属性文件中的值与BeanDefinition中相应的属性值相替换。

(5)指定国际化消息时,MessageSource对象的bean名称必须为messageSource。

(6)容器刷新过程中的钩子方法有: a. initPropertySources()由子类根据自身的应用环境初始化property资源。 b. postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory)用于在bean工厂后处理器执行前由子类对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. 启动应用后,打开%java_HOME%/bin/jconsole.exe程序,如下

这里写图片描述

c. 我使用的tomcat服务器启动的,点击第2个链接,进入的页面,如下

这里写图片描述

上面的JSON数据中就包含当前spring容器中所有的bean,是不是很神奇?这也是java MBean的一个例子。


发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表