该系列文章是本人在学习 Spring 的过程当中总结下来的,里面涉及到相关源码,可能对读者不太友好,请结合个人源码注释 Spring 源码分析 GitHub 地址 进行阅读html
Spring 版本:5.1.14.RELEASEjava
开始阅读这一系列文章以前,建议先查看《深刻了解 Spring IoC(面试题)》这一篇文章git
该系列其余文章请查看:《死磕 Spring 之 IoC 篇 - 文章导读》github
前面一系列文章都是围绕 BeanFactory 进行分析的,BeanFactory 是 Spring 底层 IoC 容器的实现,完成了 IoC 容器的基本功能。在实际的应用场景中,BeanFactory 容器有点简单,它并不适用于生产环境,咱们一般会选择 ApplicationContext。ApplicationContext 就是大名鼎鼎的 Spring 应用上下文,它不只继承了 BeanFactory 体系,还提供更加高级的功能,更加适用于咱们的正式应用环境。如如下几个功能:web
先来看看 ApplicationContext 接口的继承关系面试
能够看到 ApplicationContext 除了继承 BeanFactory 接口之外,还继承了 MessageSource、ApplicationEventPublisher、ResourceLoader 等接口spring
简单描述几个接口:bootstrap
org.springframework.core.io.ResourceLoader
,资源加载接口,用于访问不一样的资源org.springframework.context.ApplicationEventPublisher
,事件发布器接口,支持发布事件org.springframework.context.MessageSource
,消息资源接口,提供国际化的标准访问策略org.springframework.core.env.EnvironmentCapable
,环境暴露接口,Spring 应用上下文支持多环境的配置org.springframework.context.ApplicationContext
,Spring 应用上下文,仅可读org.springframework.context.ConfigurableApplicationContext
,Spring 应用上下文,支持配置相关属性接下来咱们来看看它们的实现类的继承关系(部分)缓存
简单描述上面几个关键的类:session
org.springframework.context.support.AbstractApplicationContext
,Spring 应用上下文的抽象类,实现了大部分功能,提供骨架方法交由子类去实现org.springframework.web.context.ConfigurableWebApplicationContext
,可配置的 Spring 应用上下文接口,支持 Web 应用org.springframework.context.support.AbstractRefreshableConfigApplicationContext
,支持设置 XML 文件org.springframework.web.context.support.AbstractRefreshableWebApplicationContext
,支持 Web 应用org.springframework.web.context.support.AnnotationConfigWebApplicationContext
,支持 Web 应用,能够设置 XML 文件,并能够扫描注解下面的 Beanorg.springframework.context.annotation.AnnotationConfigApplicationContext
,支持扫描注解下面的 Beanorg.springframework.web.context.support.ClassPathXmlApplicationContext
,支持设置 XML 文件,也能够从 classpath 下面扫描相关资源ApplicationContext 的子类比较多,主要根据支持 Web、支持注解、支持 XML 文件三个功能进行区分,咱们大体了解每一个实现类的做用便可。其中基本的实现都是在 AbstractApplicationContext 这个抽象类中完成的,在它的 refresh()
方法体现了 Spring 应用上下文的生命周期。AbstractApplicationContext#refresh()
这个方法能够说是 Spring 应用上下文的准备阶段,在使用 Spring 时该方法会被调用,本文就围绕它进行展述。
能够先看到个人另外一篇文章《精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化》,在 Spring MVC 启动过程当中,建立 Spring 应用上下文后会调用其 refresh()
方法进行刷新,让 Spring 应用上下文准备就绪。
org.springframework.context.support.AbstractApplicationContext
,Spring 应用上下文的抽象类,实现了大部分功能,提供骨架方法交由子类去实现
先来看看它的相关属性
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext { public static final String MESSAGE_SOURCE_BEAN_NAME = "messageSource"; public static final String LIFECYCLE_PROCESSOR_BEAN_NAME = "lifecycleProcessor"; public static final String APPLICATION_EVENT_MULTICASTER_BEAN_NAME = "applicationEventMulticaster"; static { // Eagerly load the ContextClosedEvent class to avoid weird classloader issues // on application shutdown in WebLogic 8.1. (Reported by Dustin Woods.) ContextClosedEvent.class.getName(); } /** Unique id for this context, if any. */ private String id = ObjectUtils.identityToString(this); /** Display name. */ private String displayName = ObjectUtils.identityToString(this); /** 父应用上下文 */ @Nullable private ApplicationContext parent; /** 当前应用上下文的环境 */ @Nullable private ConfigurableEnvironment environment; /** BeanFactory 的处理器 */ private final List<BeanFactoryPostProcessor> beanFactoryPostProcessors = new ArrayList<>(); /** 启动时间 */ private long startupDate; /** 是否处于激活状态 */ private final AtomicBoolean active = new AtomicBoolean(); /** 是否处于关闭状态 */ private final AtomicBoolean closed = new AtomicBoolean(); /** 启动和销毁时的锁对象 */ private final Object startupShutdownMonitor = new Object(); /** 钩子函数,用于 JVM 关闭时的回调 */ @Nullable private Thread shutdownHook; /** ResourcePatternResolver used by this context. */ private ResourcePatternResolver resourcePatternResolver; /** LifecycleProcessor for managing the lifecycle of beans within this context. */ @Nullable private LifecycleProcessor lifecycleProcessor; /** MessageSource we delegate our implementation of this interface to. */ @Nullable private MessageSource messageSource; /** 事件广播器 */ @Nullable private ApplicationEventMulticaster applicationEventMulticaster; /** 事件监听器 */ private final Set<ApplicationListener<?>> applicationListeners = new LinkedHashSet<>(); /** 早期(Spring 应用上下文还未就绪)注册的时间监听器 */ @Nullable private Set<ApplicationListener<?>> earlyApplicationListeners; /** 早期(Spring 应用上下文还未就绪)发布的事件 */ @Nullable private Set<ApplicationEvent> earlyApplicationEvents; public AbstractApplicationContext() { this.resourcePatternResolver = getResourcePatternResolver(); } public AbstractApplicationContext(@Nullable ApplicationContext parent) { this(); setParent(parent); } }
属性很少,上面都有注释
publishEvent(ApplicationEvent event)
方法,发布事件,由于它继承了 ApplicationEventPublisher 事件发布器,以下:
@Override public void publishEvent(ApplicationEvent event) { publishEvent(event, null); } protected void publishEvent(Object event, @Nullable ResolvableType eventType) { Assert.notNull(event, "Event must not be null"); // Decorate event as an ApplicationEvent if necessary ApplicationEvent applicationEvent; if (event instanceof ApplicationEvent) { applicationEvent = (ApplicationEvent) event; } else { // 若是不是 ApplicationEvent 类型的事件,则封装成 PayloadApplicationEvent 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 { // 广播该事件 getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType); } // Publish event via parent context as well... // 父容器也要发布事件 if (this.parent != null) { if (this.parent instanceof AbstractApplicationContext) { ((AbstractApplicationContext) this.parent).publishEvent(event, eventType); } else { this.parent.publishEvent(event); } } }
过程以下:
earlyApplicationEvents
不为 null
,则表示当前 Spring 应用上下文正在处于刷新阶段,尚未准备就绪,则先将这个早期事件添加至 earlyApplicationEvents
;不然,Spring 应用上下文已经准备就绪了,此时就对该事件进行广播上面的第 2
步中的 earlyApplicationEvents
若是不为 null
,为何 Spring 应用上下文尚未准备就绪呢?答案会在后面体现
addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor)
方法,添加 BeanFactoryPostProcessor 处理器,以下:
@Override public void addBeanFactoryPostProcessor(BeanFactoryPostProcessor postProcessor) { Assert.notNull(postProcessor, "BeanFactoryPostProcessor must not be null"); this.beanFactoryPostProcessors.add(postProcessor); }
直接往 beanFactoryPostProcessors
添加,BeanFactoryPostProcessor 处理器用于在 Spring 应用上下文刷新阶段对建立好的 BeanFactory 进行后缀处理
addApplicationListener(ApplicationListener<?> listener)
方法,添加事件监听器,以下:
@Override public void addApplicationListener(ApplicationListener<?> listener) { Assert.notNull(listener, "ApplicationListener must not be null"); if (this.applicationEventMulticaster != null) { this.applicationEventMulticaster.addApplicationListener(listener); } this.applicationListeners.add(listener); }
若是事件广播器不为空则将该监听器添加进去,而后再添加到本地的 applicationListeners
中
refresh()
方法,Spring 应用上下文的刷新,让 Spring 应用上下文处于准备就绪状态,以下:
/** * 刷新上下文,在哪会被调用? * 在 **Spring MVC** 中,{@link org.springframework.web.context.ContextLoader#initWebApplicationContext} 方法初始化上下文时,会调用该方法 */ @Override public void refresh() throws BeansException, IllegalStateException { // <1> 来个锁,否则 refresh() 还没结束,你又来个启动或销毁容器的操做,那不就乱套了嘛 synchronized (this.startupShutdownMonitor) { // <2> 刷新上下文环境的准备工做,记录下容器的启动时间、标记'已启动'状态、对上下文环境属性进行校验 prepareRefresh(); // <3> 建立并初始化一个 BeanFactory 对象 `beanFactory`,会加载出对应的 BeanDefinition 元信息们 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // <4> 为 `beanFactory` 进行一些准备工做,例如添加几个 BeanPostProcessor,手动注册几个特殊的 Bean prepareBeanFactory(beanFactory); try { // <5> 对 `beanFactory` 在进行一些后期的加工,交由子类进行扩展 postProcessBeanFactory(beanFactory); // <6> 执行 BeanFactoryPostProcessor 处理器,包含 BeanDefinitionRegistryPostProcessor 处理器 invokeBeanFactoryPostProcessors(beanFactory); // <7> 对 BeanPostProcessor 处理器进行初始化,并添加至 BeanFactory 中 registerBeanPostProcessors(beanFactory); // <8> 设置上下文的 MessageSource 对象 initMessageSource(); // <9> 设置上下文的 ApplicationEventMulticaster 对象,上下文事件广播器 initApplicationEventMulticaster(); // <10> 刷新上下文时再进行一些初始化工做,交由子类进行扩展 onRefresh(); // <11> 将全部 ApplicationListener 监听器添加至 `applicationEventMulticaster` 事件广播器,若是已有事件则进行广播 registerListeners(); // <12> 设置 ConversionService 类型转换器,**初始化**全部还未初始化的 Bean(不是抽象、单例模式、不是懒加载方式) finishBeanFactoryInitialization(beanFactory); // <13> 刷新上下文的最后一步工做,会发布 ContextRefreshedEvent 上下文完成刷新事件 finishRefresh(); } // <14> 若是上面过程出现 BeansException 异常 catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // <14.1> “销毁” 已注册的单例 Bean destroyBeans(); // <14.2> 设置上下文的 `active` 状态为 `false` cancelRefresh(ex); // <14.3> 抛出异常 throw ex; } // <15> `finally` 代码块 finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... // 清除相关缓存,例如经过反射机制缓存的 Method 和 Field 对象,缓存的注解元数据,缓存的泛型类型对象,缓存的类加载器 resetCommonCaches(); } } }
整个过程比较长,每个步骤都调用一个方法,过程以下:
refresh()
还没结束,你又来个启动或销毁容器的操做,那不就乱套了嘛prepareRefresh()
方法,说明:刷新上下文环境的准备工做,记录下容器的启动时间、标记'已启动'状态、对上下文环境属性进行校验obtainFreshBeanFactory()
方法,说明:建立并初始化一个 BeanFactory 对象 beanFactory
,会加载出对应的 BeanDefinition 元信息们prepareBeanFactory()
方法,说明:为 beanFactory
进行一些准备工做,例如添加几个 BeanPostProcessor,手动注册几个特殊的 BeanpostProcessBeanFactory(ConfigurableListableBeanFactory)
方法,说明:对 beanFactory
在进行一些后期的加工,交由子类进行扩展invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory)
方法,说明:执行 BeanFactoryPostProcessor 处理器,包含 BeanDefinitionRegistryPostProcessor 处理器registerBeanPostProcessors(ConfigurableListableBeanFactory)
方法,说明:对 BeanPostProcessor 处理器进行初始化,并添加至 BeanFactory 中initMessageSource()
方法,说明:设置上下文的 MessageSource 对象initApplicationEventMulticaster()
方法,说明:设置上下文的 ApplicationEventMulticaster 对象,上下文事件广播器onRefresh()
方法,说明:刷新上下文时再进行一些初始化工做,交由子类进行扩展registerListeners()
方法,说明:将全部 ApplicationListener 监听器添加至 applicationEventMulticaster
事件广播器,若是已有事件则进行广播finishBeanFactoryInitialization(ConfigurableListableBeanFactory)
方法,说明:设置 ConversionService 类型转换器,初始化全部还未初始化的 Bean(不是抽象、单例模式、不是懒加载方式)finishRefresh()
方法,说明:刷新上下文的最后一步工做,会发布 ContextRefreshedEvent 上下文完成刷新事件active
状态为 false
finally
代码块,清除相关缓存,例如经过反射机制缓存的 Method 和 Field 对象,缓存的注解元数据,缓存的泛型类型对象,缓存的类加载器能够看到该过程分为许多阶段,每一个阶段都很是关键,将在后续已经进行分析
registerShutdownHook()
方法,向 JVM 注册一个钩子函数,当 JVM 关闭时执行该函数,以下:
@Override public void registerShutdownHook() { if (this.shutdownHook == null) { // No shutdown hook registered yet. this.shutdownHook = new Thread() { @Override public void run() { synchronized (startupShutdownMonitor) { doClose(); } } }; // 为当前的 JVM 运行环境添加一个钩子函数,用于关闭当前上下文 Runtime.getRuntime().addShutdownHook(this.shutdownHook); } }
这个钩子函数也就是调用了 doClose()
方法,用于关闭当前 Spring 应用上下文
close()
方法,关闭当前 Spring 应用上下文,以下:
@Override public void close() { synchronized (this.startupShutdownMonitor) { doClose(); // If we registered a JVM shutdown hook, we don't need it anymore now: // We've already explicitly closed the context. if (this.shutdownHook != null) { try { Runtime.getRuntime().removeShutdownHook(this.shutdownHook); } catch (IllegalStateException ex) { // ignore - VM is already shutting down } } } }
关闭当前 Spring 应用上下文,也是调用 doClose()
方法,同时若是存在钩子函数则将其从 JVM 中移除,由于上面已经关闭了
doClose()
方法,关闭当前 Spring 应用上下文,以下:
protected void doClose() { // Check whether an actual close attempt is necessary... if (this.active.get() && this.closed.compareAndSet(false, true)) { // Live Beans JMX 撤销托管 LiveBeansView.unregisterApplicationContext(this); try { // Publish shutdown event. // 发布当前 Spring 应用上下文关闭事件 publishEvent(new ContextClosedEvent(this)); } catch (Throwable ex) { logger.warn("Exception thrown from ApplicationListener handling ContextClosedEvent", ex); } // Stop all Lifecycle beans, to avoid delays during individual destruction. if (this.lifecycleProcessor != null) { try { // 关闭 Lifecycle Beans this.lifecycleProcessor.onClose(); } catch (Throwable ex) { logger.warn("Exception thrown from LifecycleProcessor on context close", ex); } } // Destroy all cached singletons in the context's BeanFactory. // 销毁全部的单例 Bean destroyBeans(); // Close the state of this context itself. // 关闭底层 BeanFactory 容器 closeBeanFactory(); // Let subclasses do some final clean-up if they wish... // 提供给子类去实现,用于清理相关资源 onClose(); // Reset local application listeners to pre-refresh state. if (this.earlyApplicationListeners != null) { this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Switch to inactive. this.active.set(false); } }
主要作如下事情:
AbstractApplicationContext#prepareRefresh() 方法,以下:
// AbstractApplicationContext.java protected void prepareRefresh() { // 设置启动时间 this.startupDate = System.currentTimeMillis(); // 设置当前 ApplicationContext 的状态 this.closed.set(false); this.active.set(true); // Initialize any placeholder property sources in the context environment. // 初始化 ApplicationContext 的 Environment(上下文环境)的相关属性,交由子类去实现,若是是 Web 则会设置 ServletContext 和 ServletConfig initPropertySources(); // Validate that all properties marked as required are resolvable: // see ConfigurablePropertyResolver#setRequiredProperties // 对属性进行必要的验证 getEnvironment().validateRequiredProperties(); // Store pre-refresh ApplicationListeners... if (this.earlyApplicationListeners == null) { this.earlyApplicationListeners = new LinkedHashSet<>(this.applicationListeners); } else { // Reset local application listeners to pre-refresh state. this.applicationListeners.clear(); this.applicationListeners.addAll(this.earlyApplicationListeners); } // Allow for the collection of early ApplicationEvents, // to be published once the multicaster is available... this.earlyApplicationEvents = new LinkedHashSet<>(); }
主要作了如下事情:
earlyApplicationEvents
,注意这里建立了一个空的集合,也就是不为 null,回到前面的 publishEvent(...)
方法,若是 earlyApplicationEvents
不为 null 则会添加到这个集合里面,不会进行广播。这一步的目的就是在 Spring 应用上下文还未彻底就绪时,若是发布了事件,则须要先存储起来,等就绪后才进行广播整个过程会建立一个 DefaultListableBeanFactory 对象做为底层 IoC 容器,而后从资源文件或者根据指定路径下 .class 文件(标注了@ Component 注解)加载出全部的 BeanDefinition
AbstractApplicationContext#obtainFreshBeanFactory() 方法,以下:
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() { refreshBeanFactory(); return getBeanFactory(); }
这两个方法都是抽象方法,交由子类实现,咱们来看到 AbstractRefreshableApplicationContext 的实现
AbstractRefreshableApplicationContext#refreshBeanFactory() 方法,以下:
@Override protected final void refreshBeanFactory() throws BeansException { // 若已有 BeanFactory ,销毁它的 Bean 们,并销毁 BeanFactory if (hasBeanFactory()) { destroyBeans(); closeBeanFactory(); } try { // 建立 DefaultListableBeanFactory 对象 DefaultListableBeanFactory beanFactory = createBeanFactory(); // 指定序列化编号 beanFactory.setSerializationId(getId()); // 定制 BeanFactory 相关属性(是否容许 BeanDefinition 重复定义,是否容许循环依赖,默认都是容许) 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); } } protected DefaultListableBeanFactory createBeanFactory() { return new DefaultListableBeanFactory(getInternalParentBeanFactory()); } protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) { if (this.allowBeanDefinitionOverriding != null) { beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding); } if (this.allowCircularReferences != null) { beanFactory.setAllowCircularReferences(this.allowCircularReferences); } }
主要作如下事情:
loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
方法,交由子类实现(主要是 XML 和 Annotation 的区别)上面第 6
步会将第 2
步建立的 DefaultListableBeanFactory 设置为 Spring 应用上下文的 BeanFactory 对象,也就能够经过 getBeanFactory()
获取
咱们再来看到 loadBeanDefinitions(...)
抽象方法的实现,主要为注解和 XML 的区别,先来看到 AbstractXmlApplicationContext 的实现
AbstractXmlApplicationContext#loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 方法,以下:
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException { // Create a new XmlBeanDefinitionReader for the given BeanFactory. // 建立 XmlBeanDefinitionReader 对象 XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory); // Configure the bean definition reader with this context's // resource loading environment. // 对 XmlBeanDefinitionReader 进行环境变量的设置 beanDefinitionReader.setEnvironment(this.getEnvironment()); beanDefinitionReader.setResourceLoader(this); beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this)); // Allow a subclass to provide custom initialization of the reader, // then proceed with actually loading the bean definitions. // 对 XmlBeanDefinitionReader 进行设置,能够进行覆盖 initBeanDefinitionReader(beanDefinitionReader); // 从 Resource 们中,加载 BeanDefinition 们 loadBeanDefinitions(beanDefinitionReader); } protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException { // 从配置文件 Resource 中,加载 BeanDefinition 们 Resource[] configResources = getConfigResources(); if (configResources != null) { reader.loadBeanDefinitions(configResources); } // 从配置文件地址中,加载 BeanDefinition 们 String[] configLocations = getConfigLocations(); if (configLocations != null) { reader.loadBeanDefinitions(configLocations); } }
能够看到这里建立了 《BeanDefinition 的加载阶段(XML 文件)》这篇文章中讲到的 XmlBeanDefinitionReader 资源解析器对象,而后经过它解析 XML 配置文件,解析过程在以前的文章中已经分析过了。
配置文件怎么来的呢?
在 《精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化》的 ContextLoader#configureAndRefreshWebApplicationContext(...) 方法中能够看到,会将
web.xml
文件中配置的contextConfigLocation
设置到 Spring 应用上下文中
咱们再来看到 AnnotationConfigWebApplicationContext 的实现
AnnotationConfigWebApplicationContext#loadBeanDefinitions(DefaultListableBeanFactory beanFactory) 方法,以下:
@Override protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) { AnnotatedBeanDefinitionReader reader = getAnnotatedBeanDefinitionReader(beanFactory); ClassPathBeanDefinitionScanner scanner = getClassPathBeanDefinitionScanner(beanFactory); BeanNameGenerator beanNameGenerator = getBeanNameGenerator(); if (beanNameGenerator != null) { reader.setBeanNameGenerator(beanNameGenerator); scanner.setBeanNameGenerator(beanNameGenerator); beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator); } ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver(); if (scopeMetadataResolver != null) { reader.setScopeMetadataResolver(scopeMetadataResolver); scanner.setScopeMetadataResolver(scopeMetadataResolver); } if (!this.componentClasses.isEmpty()) { if (logger.isDebugEnabled()) { logger.debug("Registering component classes: [" + StringUtils.collectionToCommaDelimitedString(this.componentClasses) + "]"); } reader.register(ClassUtils.toClassArray(this.componentClasses)); } if (!this.basePackages.isEmpty()) { if (logger.isDebugEnabled()) { logger.debug("Scanning base packages: [" + StringUtils.collectionToCommaDelimitedString(this.basePackages) + "]"); } // 扫描指定包路径下 @Component 注解的 .class 文件,会解析出 BeanDefinition 对象 scanner.scan(StringUtils.toStringArray(this.basePackages)); } String[] configLocations = getConfigLocations(); if (configLocations != null) { for (String configLocation : configLocations) { try { Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader()); if (logger.isTraceEnabled()) { logger.trace("Registering [" + configLocation + "]"); } reader.register(clazz); } catch (ClassNotFoundException ex) { if (logger.isTraceEnabled()) { logger.trace("Could not load class for config location [" + configLocation + "] - trying package scan. " + ex); } int count = scanner.scan(configLocation); if (count == 0 && logger.isDebugEnabled()) { logger.debug("No component classes found for specified class/package [" + configLocation + "]"); } } } } } protected ClassPathBeanDefinitionScanner getClassPathBeanDefinitionScanner(DefaultListableBeanFactory beanFactory) { return new ClassPathBeanDefinitionScanner(beanFactory, true, getEnvironment()); }
咱们主要看到关键的一步,会建立一个 ClassPathBeanDefinitionScanner 扫描器对象,而后调用其 scan(String... basePackages) 方法去扫描指定包路径下的 .class 文件,整个扫描过程在 《BeanDefinition 的解析过程(面向注解)》 这篇文章中已经分析过了
AbstractApplicationContext#prepareBeanFactory(ConfigurableListableBeanFactory) 方法,以下:
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 设置 ClassLoader 类加载器 beanFactory.setBeanClassLoader(getClassLoader()); // 设置 BeanExpressionResolver 表达式语言处理器,Spring 3 开始增长了对语言表达式的支持,例如可使用 #{bean.xxx} 的形式来调用这个 Bean 的属性值 beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader())); // 添加一个默认的 PropertyEditorRegistrar 属性编辑器 beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment())); /* * 添加一个 BeanPostProcessor 处理器,ApplicationContextAwareProcessor,初始化 Bean 的**前置**处理 * 这个 BeanPostProcessor 实际上是对几种 Aware 接口的处理,调用其 setXxx 方法 * 能够跳到 AbstractAutowireCapableBeanFactory 的 initializeBean(...) 方法(调用 Bean 的初始化方法)中看看 */ beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 忽略 Aware 回调接口做为依赖注入接口 beanFactory.ignoreDependencyInterface(EnvironmentAware.class); beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class); beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class); beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class); beanFactory.ignoreDependencyInterface(MessageSourceAware.class); beanFactory.ignoreDependencyInterface(ApplicationContextAware.class); // 设置几个自动装配的特殊规则,当你自动注入下面这些类型的 Bean 时,注入的就是右边的值 // 能够看到 ApplicationContext.class 对应当前对象 beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory); beanFactory.registerResolvableDependency(ResourceLoader.class, this); beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this); beanFactory.registerResolvableDependency(ApplicationContext.class, this); // Register early post-processor for detecting inner beans as ApplicationListeners. // 添加一个 BeanPostProcessor 处理器,ApplicationListenerDetector,用于装饰监听器 // 初始化 Bean 的时候,若是是 ApplicationListener 类型且为单例模式,则添加到 Spring 应用上下文 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 增长对 AspectJ 的支持,AOP 相关 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())); } // 注册几个 ApplicationContext 上下文默认的 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()); } }
主要作如下事情:
ApplicationContextAwareProcessor
,相关 Aware 回调接口的实现,调用其 setXxx 方法ApplicationListenerDetector
,初始化 Bean 的时候,若是是 ApplicationListener 类型且为单例模式,则添加到 Spring 应用上下文有序地执行全部 BeanFactoryPostProcessor(包括 BeanDefinitionRegistryPostProcessor)处理器,例如 @Bean
等注解定义的 Bean 的就是经过 BeanDefinitionRegistryPostProcessor 处理器接续出来的
该抽象方法交由子类实现,例如 AbstractRefreshableWebApplicationContext#postProcessBeanFactory(ConfigurableListableBeanFactory) 方法,以下:
@Override protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { // 添加 ServletContextAwareProcessor 到 BeanFactory 容器中, // 该 processor 实现 BeanPostProcessor 接口,主要用于将 ServletContext 传递给实现了 ServletContextAware 接口的 bean beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); // 忽略 ServletContextAware、ServletConfigAware,上面的 ServletContextAwareProcessor 已代替 beanFactory.ignoreDependencyInterface(ServletContextAware.class); beanFactory.ignoreDependencyInterface(ServletConfigAware.class); // 注册 WEB 应用特定的域(scope)到 beanFactory 中,以便 WebApplicationContext 可使用它们。 // 好比'request','session','globalSession','application' WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext); // 注册 WEB 应用特定的 Environment bean 到 beanFactory 中,以便 WebApplicationContext 可使用它们 // 如:'contextParameters','contextAttributes' WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig); }
添加 ServletContext 相关内容
AbstractApplicationContext#invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory) 方法,以下:
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 执行全部的BeanFactoryPostProcessor处理器 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) // 在 prepareBeanFactory() 方法中也有相同操做 if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) { beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader())); } }
这里借助于 PostProcessorRegistrationDelegate 这个类执行全部 BeanFactoryPostProcessor 处理器,对前面建立的 BeanFactory 进行后置处理
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors 方法,以下(方法比较长,可直接查看下面的总结):
public static void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) { // Invoke BeanDefinitionRegistryPostProcessors first, if any. Set<String> processedBeans = new HashSet<>(); // <1> 执行当前 Spring 应用上下文和底层 BeanFactory 容器中的 BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor 们的处理 if (beanFactory instanceof BeanDefinitionRegistry) { BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory; List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); // <1.1> 先遍历当前 Spring 应用上下文中的 `beanFactoryPostProcessors`,若是是 BeanDefinitionRegistryPostProcessor 类型则进行处理 for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) { if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) { BeanDefinitionRegistryPostProcessor registryProcessor = (BeanDefinitionRegistryPostProcessor) postProcessor; // 执行 registryProcessor.postProcessBeanDefinitionRegistry(registry); // 添加,以供后续执行其余 `postProcessBeanFactory(registry)` 方法 registryProcessors.add(registryProcessor); } else { regularPostProcessors.add(postProcessor); } } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // Separate between BeanDefinitionRegistryPostProcessors that implement // PriorityOrdered, Ordered, and the rest. // 临时变量,用于临时保存 BeanFactory 容器中的 BeanDefinitionRegistryPostProcessor 对象 List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); // First, invoke the BeanDefinitionRegistryPostProcessors that implement PriorityOrdered. // <1.2> 获取底层 BeanFactory 容器中全部 BeanDefinitionRegistryPostProcessor 类型的 Bean 们,遍历进行处理 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 若是实现了 PriorityOrdered 接口,则获取到对应的 Bean if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 初始化 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 临时保存起来 registryProcessors.addAll(currentRegistryProcessors); // 执行 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清理 currentRegistryProcessors.clear(); // Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered. // <1.3> 获取底层 BeanFactory 容器中全部 BeanDefinitionRegistryPostProcessor 类型的 Bean 们,遍历进行处理 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 若是实现了 Ordered 接口而且没有执行过,则获取到对应的 Bean if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) { // Ordered类型 // 初始化 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 临时保存起来 registryProcessors.addAll(currentRegistryProcessors); // 执行 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清理 currentRegistryProcessors.clear(); // Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear. boolean reiterate = true; while (reiterate) { reiterate = false; // <1.4> 获取底层 BeanFactory 容器中全部 BeanDefinitionRegistryPostProcessor 类型的 Bean 们,遍历进行处理 postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { // 若是该 BeanDefinitionRegistryPostProcessors 在上述过程当中没有执行过,则获取到对应的 Bean if (!processedBeans.contains(ppName)) { // 初始化 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); reiterate = true; } } // 排序 sortPostProcessors(currentRegistryProcessors, beanFactory); // 临时保存起来 registryProcessors.addAll(currentRegistryProcessors); // 执行 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); // 清理 currentRegistryProcessors.clear(); } // Now, invoke the postProcessBeanFactory callback of all processors handled so far. /* * <1.5> 上述执行完当前 Spring 应用上下文和底层 BeanFactory 容器中全部 BeanDefinitionRegistryPostProcessor 处理器中的 postProcessBeanDefinitionRegistry(registry) 方法后, * 接下来执行它们的 postProcessBeanFactory(beanFactory) 方法 * * 注意:BeanDefinitionRegistryPostProcessor 继承 BeanFactoryPostProcessor 接口 */ invokeBeanFactoryPostProcessors(registryProcessors, beanFactory); /* * <1.6> 这里咱们执行当前 Spring 应用上下文中 BeanFactoryPostProcessor 处理器(非 BeanDefinitionRegistryPostProcessors 类型)的 * postProcessBeanFactory(beanFactory) 方法 * * 例如:PropertyPlaceholderConfigurer、PropertySourcesPlaceholderConfigurer */ invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory); } // <2> 执行当前 Spring 应用上下文中的 BeanFactoryPostProcessor 处理器的 postProcessBeanFactory(beanFactory) 方法 else { // Invoke factory processors registered with the context instance. invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let the bean factory post-processors apply to them! // <3> 获取底层 BeanFactory 容器中全部 BeanFactoryPostProcessor 类型的 Bean 们 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false); // Separate between BeanFactoryPostProcessors that implement PriorityOrdered, // Ordered, and the rest. List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); List<String> orderedPostProcessorNames = new ArrayList<>(); List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { if (processedBeans.contains(ppName)) { // 上面已经执行过了则跳过 // skip - already processed in first phase above } else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // PriorityOrdered priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class)); } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // Ordered orderedPostProcessorNames.add(ppName); } else { // nonOrder nonOrderedPostProcessorNames.add(ppName); } } // First, invoke the BeanFactoryPostProcessors that implement PriorityOrdered. // <3.1> PriorityOrdered 类型的 BeanFactoryPostProcessor 对象 // 排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 执行 invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory); // Next, invoke the BeanFactoryPostProcessors that implement Ordered. // <3.2> Ordered 类型的 BeanFactoryPostProcessor 对象 List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String postProcessorName : orderedPostProcessorNames) { orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 排序 sortPostProcessors(orderedPostProcessors, beanFactory); // 执行 invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory); // Finally, invoke all other BeanFactoryPostProcessors. // <3.2> nonOrdered 的 BeanFactoryPostProcessor 对象 List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String postProcessorName : nonOrderedPostProcessorNames) { nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class)); } // 无需排序,直接执行 invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory); // Clear cached merged bean definitions since the post-processors might have // modified the original metadata, e.g. replacing placeholders in values... beanFactory.clearMetadataCache(); }
主要作如下事情:
总结:有序地执行全部 BeanFactoryPostProcessor(包括 BeanDefinitionRegistryPostProcessor)处理器
将全部已加载出来的 BeanPostProcessor 类型的 BeanDefinition 经过依赖查找获取到 Bean 们,而后有序的添加至 BeanFactory 中
AbstractApplicationContext#registerBeanPostProcessors(ConfigurableListableBeanFactory) 方法,以下:
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }
这里也借助于 PostProcessorRegistrationDelegate 这个类注册全部 BeanPostProcessor 处理器,以下:
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { // <1> 获取全部的 BeanPostProcessor 类型的 beanName // 这些 beanName 都已经所有加载到容器中去,可是没有实例化 String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false); // Register BeanPostProcessorChecker that logs an info message when // a bean is created during BeanPostProcessor instantiation, i.e. when // a bean is not eligible for getting processed by all BeanPostProcessors. // <2> 记录全部的 BeanPostProcessor 数量,为何加 1 ?由于下面又添加了一个 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; // 注册 BeanPostProcessorChecker,它主要是用于在 BeanPostProcessor 实例化期间记录日志 // 当 Spring 中高配置的后置处理器尚未注册就已经开始了 bean 的实例化过程,这个时候便会打印 BeanPostProcessorChecker 中的内容 beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered, Ordered, and the rest. // <3> 开始注册 BeanPostProcessor // 实现了 `PriorityOrdered` 接口的 BeanPostProcessor 对应的 Bean 集合 List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); // MergedBeanDefinitionPostProcessor 类型对应的 Bean 集合 List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); // 实现了 `Ordered` 接口的 BeanPostProcessor 对应的 beanName 集合 List<String> orderedPostProcessorNames = new ArrayList<>(); // 没有顺序的 BeanPostProcessor 对应的 beanName 集合 List<String> nonOrderedPostProcessorNames = new ArrayList<>(); for (String ppName : postProcessorNames) { // PriorityOrdered if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 调用 getBean(...) 方法获取该 BeanPostProcessor 处理器的 Bean 对象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } // Ordered else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { orderedPostProcessorNames.add(ppName); } // 无序 else { nonOrderedPostProcessorNames.add(ppName); } } // First, register the BeanPostProcessors that implement PriorityOrdered. // 第一步,对全部实现了 PriorityOrdered 的 BeanPostProcessor 进行排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 进行注册,也就是添加至 DefaultListableBeanFactory 中 registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. // 第二步,获取全部实现了 Ordered 接口的 BeanPostProcessor 对应的 Bean 们 List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(); for (String ppName : orderedPostProcessorNames) { // 调用 getBean(...) 方法获取该 BeanPostProcessor 处理器的 Bean 对象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } // 对全部实现了 Ordered 的 BeanPostProcessor 进行排序 sortPostProcessors(orderedPostProcessors, beanFactory); // 进行注册,也就是添加至 DefaultListableBeanFactory 中 registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. // 第三步注册全部无序的 BeanPostProcessor List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(); for (String ppName : nonOrderedPostProcessorNames) { // 调用 getBean(...) 方法获取该 BeanPostProcessor 处理器的 Bean 对象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } // 注册,无需排序 registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. // 最后,注册全部的 MergedBeanDefinitionPostProcessor 类型的 Bean 们 sortPostProcessors(internalPostProcessors, beanFactory); registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). // 从新注册 ApplicationListenerDetector(探测器),用于探测内部 ApplicationListener 类型的 Bean // 在彻底初始化 Bean 后,若是是 ApplicationListener 类型且为单例模式,则添加到 Spring 应用上下文 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }
主要作如下事情:
3
步添加的 BeanPostProcessor 若是是 MergedBeanDefinitionPostProcessor 类型,会再次添加(先移除再添加,也就是将顺序日后挪)对与上述第
4
步是否疑惑?个人理解是 MergedBeanDefinitionPostProcessor 主要是依赖注入的实现,须要保证当前 Spring Bean 的相关初始化工做已完成,而后再进行依赖注入
总结:将全部已加载出来的 BeanPostProcessor 类型的 BeanDefinition 经过依赖查找获取到 Bean 们,而后有序的添加至 BeanFactory 中
AbstractApplicationContext#initMessageSource() 方法,以下:
protected void initMessageSource() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 若是当前上下文中包含名称为 `messageSource` 的 Bean 对象 if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) { this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class); // 若是有父 ApplicationContext,而且 `messageSource` 为 HierarchicalMessageSource 对象,分级处理的 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. // 若是 `messageSource` 没有注册父 MessageSource,则设置为父类上下文的的 MessageSource hms.setParentMessageSource(getInternalParentMessageSource()); } } if (logger.isTraceEnabled()) { logger.trace("Using MessageSource [" + this.messageSource + "]"); } } else { // Use empty MessageSource to be able to accept getMessage calls. // 使用空 MessageSource 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 + "]"); } } }
初始化当前 Spring 应用上下文的 MessageSource 对象,MessageSource 对象和国际化文案相关,Spring 默认状况不提供国际化文案,可是 MessageSource Bean 对象(空实现)是存在的,在 Spring Boot 中有实现,参考 MessageSourceAutoConfiguration 自动装配类
AbstractApplicationContext#initApplicationEventMulticaster() 方法,以下:
protected void initApplicationEventMulticaster() { ConfigurableListableBeanFactory beanFactory = getBeanFactory(); // 若是当前上下文中包含名称为 `applicationEventMulticaster` 的 Bean 对象 if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) { this.applicationEventMulticaster = beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class); } else { // 没有则新建 SimpleApplicationEventMulticaster,并将该 Bean 注册至当前上下文 this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory); beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster); } }
初始化当前 Spring 应用上下文的 ApplicationEventMulticaster 事件广播器对象,Spring 默认状况下为 SimpleApplicationEventMulticaster 对象
AbstractApplicationContext#onRefresh() 方法,空方法,交由子类实现,如 AbstractRefreshableWebApplicationContext 的实现
@Override protected void onRefresh() { this.themeSource = UiApplicationContextUtils.initThemeSource(this); }
Web 场景下的 Spring 应用上下文会初始化 ThemeSource 对象
AbstractApplicationContext#registerListeners() 方法,以下:
protected void registerListeners() { // <1> 将当前 Spring 应用上下文已有的事件监听器依次添加至事件广播器 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // Do not initialize FactoryBeans here: We need to leave all regular beans // uninitialized to let post-processors apply to them! // <2> 从底层 BeanFactory 容器中获取全部 ApplicationListener 类型的 beanName 们(还未初始化),而后依次添加至事件广播器 String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false); for (String listenerBeanName : listenerBeanNames) { getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName); } // Publish early application events now that we finally have a multicaster... //<3> 至此,已经完成将事件监听器所有添加至事件广播器,接下来将早期的事件经过该事件广播器广播到全部的事件监听器 // 早期事件:在当前 Spring 应用上下文刷新的过程当中已经发布的事件(此时发布不会被监听到,由于事件监听器才刚所有找到,须要到此处经过事件广播器进行广播) Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; /** * 将 `earlyApplicationEvents` 置为 `null` * 这里很关键!!!后续发布的事件再也不是早期事件,会当即被事件广播器广播。由于当前 Spring 应用中的事件广播器已经就绪了,事件监听器也都获取到了(虽然尚未初始化) * 不过在下面广播的时候,若是事件监听器可以处理该事件,则会经过依赖注入的方式初始化该事件监听器 */ this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { // 广播该事件,可以处理该事件的事件监听器会被初始化 getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
主要作如下事情:
earlyApplicationEvents
早期事件,而后将 earlyApplicationEvents
置为 null
早期事件:在当前 Spring 应用上下文刷新的过程当中已经发布的事件(此时发布不会被监听到,由于事件监听器才刚所有找到,须要到此处经过事件广播器进行广播)
上面第 3
步会将 earlyApplicationEvents
置为 null
,前面的 publishEvent 方法中你能够看到,若是该对象为 null
则会直接广播事件
主要为底层 BeanFactory 容器设置 ConversionService 类型转换器,初始化全部还未初始化的 Bean(不是抽象、单例模式、不是懒加载方式)
AbstractApplicationContext#finishBeanFactoryInitialization(ConfigurableListableBeanFactory) 方法,以下:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) { // 若是底层 BeanFactory 容器包含 ConversionService 类型转换器,则初始化并设置到底层 BeanFactory 容器的属性中 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 容器没有设置 StringValueResolver 解析器,则添加一个 PropertySourcesPropertyResolver 解析器 if (!beanFactory.hasEmbeddedValueResolver()) { beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal)); } // Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early. // 提早初始化 LoadTimeWeaverAware 类型的 Bean,AOP 相关 String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false); for (String weaverAwareName : weaverAwareNames) { getBean(weaverAwareName); } // Stop using the temporary ClassLoader for type matching. // 将临时的 ClassLoader 置为 null,它主要用于 AOP beanFactory.setTempClassLoader(null); // Allow for caching all bean definition metadata, not expecting further changes. // 冻结底层 BeanFactory 容器全部的 BeanDefinition,目的是不但愿再去修改 BeanDefinition beanFactory.freezeConfiguration(); // 【重点】初始化全部还未初始化的 Bean(不是抽象、单例模式、不是懒加载方式),依赖查找 beanFactory.preInstantiateSingletons(); }
咱们看到最后一步,会调用 DefaultListableBeanFactory 的 preInstantiateSingletons() 方法,初始化全部还未初始化的 Bean(不是抽象、单例模式、不是懒加载方式),依赖查找
DefaultListableBeanFactory#preInstantiateSingletons() 方法,以下:
@Override public void preInstantiateSingletons() throws BeansException { if (logger.isTraceEnabled()) { logger.trace("Pre-instantiating singletons in " + this); } // Iterate over a copy to allow for init methods which in turn register new bean definitions. // While this may not be part of the regular factory bootstrap, it does otherwise work fine. // 复制一份本地的全部 beanNames 集合 List<String> beanNames = new ArrayList<>(this.beanDefinitionNames); // Trigger initialization of all non-lazy singleton beans... // 遍历全部的 beanName for (String beanName : beanNames) { // 从容器中获取 beanName 相应的 RootBeanDefinition 对象 RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName); // 若是该 Bean 的定义为:不是抽象、单例模式、不是懒加载方式,则进行初始化 if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) { // 若是是 FactoryBean 类型的 Bean if (isFactoryBean(beanName)) { // 初始化 FactoryBean 类型自己这个 Bean,注意这里在 beanName 的前面添加了一个 '&' Object bean = getBean(FACTORY_BEAN_PREFIX + beanName); // 若是这个 FactoryBean 为 SmartFactoryBean 类型,而且须要提早初始化 // 则初始 beanName 对应的 Bean,也就是调用 FactoryBean 的 getObject() 方法 if (bean instanceof FactoryBean) { final FactoryBean<?> factory = (FactoryBean<?>) bean; boolean isEagerInit; if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) { isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>) ((SmartFactoryBean<?>) factory)::isEagerInit, getAccessControlContext()); } else { isEagerInit = (factory instanceof SmartFactoryBean && ((SmartFactoryBean<?>) factory).isEagerInit()); } if (isEagerInit) { getBean(beanName); } } } else { // 初始化 beanName 对应的 Bean getBean(beanName); } } } // Trigger post-initialization callback for all applicable beans... for (String beanName : beanNames) { Object singletonInstance = getSingleton(beanName); if (singletonInstance instanceof SmartInitializingSingleton) { final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance; if (System.getSecurityManager() != null) { AccessController.doPrivileged((PrivilegedAction<Object>) () -> { smartSingleton.afterSingletonsInstantiated(); return null; }, getAccessControlContext()); } else { smartSingleton.afterSingletonsInstantiated(); } } } }
首先会遍历因此的 beanName
,若是该 Bean 的定义知足下面三个条件,则进行初始化过程
实际就是经过 getBean(String beanName)
方法进行初始化,在前面的 《开启 Bean 的加载》 等文章中已经分析过了。注意,若是是 FactoryBean 类型的 Bean,须要先初始化 FactoryBean 自己这个 Bean,beanName
前面加 &
,而后再初始化这个 beanName
,也就是调用 FactoryBean#getObject() 方法
在初始化全部的 Bean 后,其实还有一个初始化完成阶段,会遍历全部已初始化好的 Bean,若是是 SmartInitializingSingleton 类型,则调用这个 Bean 的 afterSingletonsInstantiated() 方法
SmartInitializingSingleton 的做用?
经过 getBean(beanName) 初始化一个 Bean 的时候也会初始化依赖的对象,这样可能会出现过早的初始化问题(例如可能有些 BeanPostProcessor 还未添加进来就初始化了),致使相关 Bean 可能还未彻底初始化,Spring 4.1 以后就提供了 SmartInitializingSingleton 接口机制让你能够确保 Bean 的初始化行为比较正常。
还有就是在全部的 Bean 完成初始化后,能够在这里进行注解的相关处理,例如 @EventListener 注解就是经过 EventListenerMethodProcessor 实现的,会将@EventListener 注解标注的方法解析成 ApplicationListener 事件监听器,并注册至 Spring 应用上下文。
AbstractApplicationContext#finishRefresh() 方法,以下:
protected void finishRefresh() { // Clear context-level resource caches (such as ASM metadata from scanning). // 清除当前 Spring 应用上下文中的缓存,例如经过 ASM(Java 字节码操做和分析框架)扫描出来的元数据 clearResourceCaches(); // Initialize lifecycle processor for this context. // 初始化 LifecycleProcessor 到当前上下文的属性中 initLifecycleProcessor(); // Propagate refresh to lifecycle processor first. // 经过 LifecycleProcessor 启动 Lifecycle 生命周期对象 getLifecycleProcessor().onRefresh(); // 发布 ContextRefreshedEvent 事件,会经过事件广播器进行广播,可经过自定义监听器在当前 Spring 应用上下文初始化完后进行相关操做 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. // 若是当前 Spring 应用上下文的 Environment 环境中配置了 'spring.liveBeansView.mbeanDomain' // 则向 MBeanServer(JMX 代理层的核心)托管 Live Beans,也就是让 Spring Bean 桥接到 MBeanServer LiveBeansView.registerApplicationContext(this); }
主要作如下事情:
ContextRefreshedEvent
上下文刷新完成事件,会经过事件广播器进行广播spring.liveBeansView.mbeanDomain
,则向 MBeanServer(JMX 代理层的核心)托管 Live Beans,也就是让 Spring Bean 桥接到 MBeanServerApplicationContext 就是大名鼎鼎的 Spring 应用上下文,底层 IoC 容器就是 DefaultListableBeanFactory 这个类,在它的基础上提供出更多的高级功能,更加适用于正式的应用环境。子类 AbstractApplicationContext 抽象类实现了大部分功能,调用它的 refresh()
方法可让 Spring 应用上下文处于准备就绪状态,使用 Spring 都会显示或者隐式地调用该方法,这个方法中有很是多核心的步骤,这些步骤在上面的每一个小节中依次进行分析过,具体过程可查看上面的每一个小节。
AbstractApplicationContext#refresh() 方法在哪被调用?
能够看到个人另外一篇文章《精尽Spring MVC源码分析 - WebApplicationContext 容器的初始化》,在 Spring MVC 启动过程当中,建立 Spring 应用上下文后,(在 ContextLoader#configureAndRefreshWebApplicationContext 方法中)会调用其
refresh()
方法进行刷新,让 Spring 应用上下文准备就绪。
至此,Spring IoC 的相关内容差很少都讲完了,关于 @Bean
等注解的处理在下一篇文章中进行分析。