Spring源码–AbstractApplicationContext
概述
江湖上流传这样一个传说,只要把spring的refresh()搞明白,spring就学的七七八八了。今天来盘一下refresh方法,这个这是一个困难点了。
学习refresh()先要知道这个方法承接的类,对于AbstractApplicationContext类,前面也介绍了,他的实现类ClassPathXmlApplicationContext类,执行下方代码:
ApplicationContext applicationContext= new ClassPathXmlApplicationContext("x.xml");
B b=applicationContext.getBean(B.class);
在创建对象使用构造方法时候调用了refresh方法,也就是说,在程序启动,构建bean的过程中执行refresh方法 。下面我们看下具体的refresh方法包括那些内容。
源码
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备更新上下文,设置开始时间,标记活动标志,初始化配置文件中的占位符
prepareRefresh();
// 一、 web工程 AbstractRefreshableApplicationContext
// 将 bean 定义加载到给定的 BeanFactory 中
// 二、 SpringBoot GenericApplicationContext,实际 register 过程在 invokeBeanFactoryPostProcessors 中
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 准备 BeanFactory 以便在此上下文中使用。
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 在 AbstractApplicationContext#postProcessBeanFactory 为空实现,留给子类做扩展,不同 ApplicationContext 实现不同,不作详细描述
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// Spring 的 SPI
// 先调用 BeanDefinitionRegistryPostProcessor 和 ImportBeanDefinitionRegistrar 的实现类
// 再调用 BeanFactoryPostProcessor 各个实现类的 postProcessBeanFactory(factory) 方法
// 例如:ConfigurationClassPostProcessor 会扫描 <context:component-scan/> 和 @SpringBootApplication(scanBasePackages = "") 中的Component,并且将 @Configuration 类中的 @Bean register 到 BeanFactory 中
// 扩展例如:MyBatis MapperScannerConfigurer 和 MapperScannerRegistrar,扫描Mapper register 到 BeanFactory 中
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册 BeanPostProcessor 的实现类,不同于刚刚的 BeanFactoryPostProcessor
// BeanPostProcessor 接口两个方法 postProcessBeforeInitialization 和 postProcessAfterInitialization 会在 Bean 初始化之前和之后调用
// 这边 Bean 还没初始化,下面的 finishBeanFactoryInitialization 才是真正的初始化方法
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化当前 ApplicationContext 的 MessageSource,解析消息的策略接口,用于支持消息的国际化和参数化
// Spring 两个开箱即用的实现 ResourceBundleMessageSource 和 ReloadableResourceBundleMessageSource
initMessageSource();
// Initialize event multicaster for this context.
// 初始化当前 ApplicationContext 的事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 典型模板方法
// 子类可以在实例化 bean 之前,做一些初始化工作,SpringBoot 会在这边启动 Web 服务
onRefresh();
// Check for listener beans and register them.
// 向 initApplicationEventMulticaster() 初始化的 applicationEventMulticaster 注册事件监听器,就是实现 ApplicationListener 接口类
// 观察者模式,例如实现了 ApplicationEvent,通过 ApplicationEventPublisher#publishEvent(),可以通知到各个 ApplicationListener#onApplicationEvent
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 初始化所有的 singletons bean(lazy-init 的除外)
// Spring bean 初始化核心方法
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// ApplicationEventPublisher#publishEvent() 初始化完成(ContextRefreshedEvent)事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// Destroy already created singletons to avoid dangling resources.
// destroy 已经创建的 singleton 避免占用资源
destroyBeans();
// Reset 'active' flag.
// 重置'有效'标志
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// Reset common introspection caches in Spring's core, since we
// might not ever need metadata for singleton beans anymore...
// 重置Spring核心中的常见内省缓存,因为可能不再需要单例bean的元数据了...
resetCommonCaches();
}
}
}
整个refresh方法中,我的理解就是在围绕bean在给bean提供环境,其中bean整个运转的生命周期。下面排了下整个方法中包括的内容:
- prepareRefresh();
- ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
- prepareBeanFactory(beanFactory);
- postProcessBeanFactory(beanFactory);
- invokeBeanFactoryPostProcessors(beanFactory);
- registerBeanPostProcessors(beanFactory);
- initMessageSource();
- initApplicationEventMulticaster();
- onRefresh();
- registerListeners();
- finishBeanFactoryInitialization(beanFactory);
- finishRefresh();
- destroyBeans();
- cancelRefresh(ex);
- resetCommonCaches();
刺激时刻来了,可以开始一个个解析上面的方法了,刺激!!!。
prepareRefresh()
这个是refresh()方法的第一步,准备更新上下文,设置开始时间,标记活动标志,初始化配置文件中的占位符。
/**
* Prepare this context for refreshing, setting its startup date and
* active flag as well as performing any initialization of property sources.
* 准备此上下文以进行刷新、设置其启动日期和活动标志以及执行任何属性源的初始化。
*/
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isDebugEnabled()) {
if (logger.isTraceEnabled()) {
logger.trace("Refreshing " + this);
}
else {
logger.debug("Refreshing " + getDisplayName());
}
}
// 初始化上下文环境中的任何占位符属性源。
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<>();
}
obtainFreshBeanFactory()
前期方法都是在进行准备工作,obtainFreshBeanFactory是告诉子类刷新内部 bean 工厂,返回一个BeanFactory,相当于创建一个工程对象。
/**
* Tell the subclass to refresh the internal bean factory.
* @return the fresh BeanFactory instance
* @see #refreshBeanFactory()
* @see #getBeanFactory()
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
/**
* This implementation performs an actual refresh of this context's underlying
* bean factory, shutting down the previous bean factory (if any) and
* initializing a fresh bean factory for the next phase of the context's lifecycle.
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 1. createBeanFactory(); 为此上下文创建内部 BeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 2. customizeBeanFactory(beanFactory);
// 定制 BeanFactory,是否允许 BeanDefinition 覆盖、是否允许循环引用
customizeBeanFactory(beanFactory);
// 3. loadBeanDefinitions(beanFactory);
// 通过 BeanDefinitionReader 解析 xml 文件,解析封装信息到 BeanDefinition,并将其 register 到 BeanFactory 中
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
prepareBeanFactory(beanFactory)
在obtainFreshBeanFactory创建了BeanFactory对象,prepareBeanFactory()方法是对BeanFactory对象的属性包装,这个方法主要处理内容:
- 设置 BeanFactory 的类加载器
- 添加几个 BeanPostProcessor,
- 实例化几个特殊的 bean
/**
* Configure the factory's standard context characteristics,
* such as the context's ClassLoader and post-processors.
* @param beanFactory the BeanFactory to configure
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 1. 设置 BeanFactory 的类加载器
// 2. 添加几个 BeanPostProcessor,
// 3. 实例化几个特殊的 bean
//告诉内部bean工厂使用上下文的类加载器等。
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 使用上下文回调配置bean工厂。
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
// BeanFactory interface not registered as resolvable type in a plain factory.在普通工厂中没有注册为可解析类型。
// MessageSource registered (and found for autowiring) as a bean.消息源注册为bean(并找到用于自动连接)。
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.
//将用于检测内部bean的早期后处理器注册为应用程序监听器。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
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()));
}
// Register default environment beans.
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());
}
}
postProcessBeanFactory(beanFactory)
在 AbstractApplicationContext#postProcessBeanFactory 为空实现,留给子类做扩展,不同 ApplicationContext 实现不同,不作详细描述
/**
* Modify the application context's internal bean factory after its standard
* initialization. All bean definitions will have been loaded, but no beans
* will have been instantiated yet. This allows for registering special
* BeanPostProcessors etc in certain ApplicationContext implementations.
* @param beanFactory the bean factory used by the application context
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
invokeBeanFactoryPostProcessors(beanFactory)
postProcessBeanFactory()方法构建了BeanFactory的PostProcessors,invokeBeanFactoryPostProcessors()方法则是调用postProcessBeanFactory()方法所准备的PostProcessors。
/**
* Instantiate and invoke all registered BeanFactoryPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before singleton instantiation.
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
obtainFreshBeanFactory(),prepareBeanFactory(),postProcessBeanFactory(),invokeBeanFactoryPostProcessors()等4个方法是对BeanFactory做处理。
registerBeanPostProcessors(beanFactory)
这个对于Bean 的PostProcessor的bean进行注册,以及实例化。这句话不好读,这里面有一个PostProcessor他是对于bean进行增强处理的,但是PostProcessor也是以bean的形式进行运转的。
/**
* Instantiate and register all BeanPostProcessor beans,
* respecting explicit order if given.
* <p>Must be called before any instantiation of application beans.
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
initMessageSource()
初始化当前 ApplicationContext 的 MessageSource,解析消息的策略接口,用于支持消息的国际化和参数化
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
*/
protected void initMessageSource() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(MESSAGE_SOURCE_BEAN_NAME)) {
this.messageSource = beanFactory.getBean(MESSAGE_SOURCE_BEAN_NAME, MessageSource.class);
// Make MessageSource aware of parent MessageSource.
if (this.parent != null && this.messageSource instanceof HierarchicalMessageSource) {
HierarchicalMessageSource hms = (HierarchicalMessageSource) this.messageSource;
if (hms.getParentMessageSource() == null) {
// Only set parent context as parent MessageSource if no parent MessageSource
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
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 + "]");
}
}
}
initApplicationEventMulticaster()
初始化当前 ApplicationContext 的事件广播器。
/**
* Initialize the ApplicationEventMulticaster.
* Uses SimpleApplicationEventMulticaster if none defined in the context.
* @see org.springframework.context.event.SimpleApplicationEventMulticaster
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (beanFactory.containsLocalBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME)) {
this.applicationEventMulticaster =
beanFactory.getBean(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, ApplicationEventMulticaster.class);
if (logger.isTraceEnabled()) {
logger.trace("Using ApplicationEventMulticaster [" + this.applicationEventMulticaster + "]");
}
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
if (logger.isTraceEnabled()) {
logger.trace("No '" + APPLICATION_EVENT_MULTICASTER_BEAN_NAME + "' bean, using " +
"[" + this.applicationEventMulticaster.getClass().getSimpleName() + "]");
}
}
}
onRefresh()
这是一个空的方法,集成的实现类可以按照自己的处理方式进行特殊处理,典型的模板模式
/**
* Template method which can be overridden to add context-specific refresh work.
* Called on initialization of special beans, before instantiation of singletons.
* <p>This implementation is empty.
* @throws BeansException in case of errors
* @see #refresh()
*/
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
registerListeners()
registerListeners()方法是呼应initApplicationEventMulticaster()方法,initApplicationEventMulticaster()进行事件的广播,而registerListeners()方法则是进行时间的监听,例如aop代理监听也在这里进行初试化处理。
/**
* Add beans that implement ApplicationListener as listeners.
* Doesn't affect other listeners, which can be added without being beans.
*/
protected void registerListeners() {
// Register statically specified listeners first.
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!
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...
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
finishBeanFactoryInitialization(beanFactory)
这个方法是 核心中的核心内容,这个方法进行了bean的创建,初始化和实例化,这个在后面代码实际操作,打断点时候核心讲解的内容。
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
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));
}
// Register a default embedded value resolver if no BeanFactoryPostProcessor
// (such as a PropertySourcesPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
finishRefresh()
这个是refresh方法的收尾,进行容器的发布。
/**
* Finish the refresh of this context, invoking the LifecycleProcessor's
* onRefresh() method and publishing the
* {@link org.springframework.context.event.ContextRefreshedEvent}.
*/
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
// Participate in LiveBeansView MBean, if active.
LiveBeansView.registerApplicationContext(this);
}
refresh是集成ConfigurableApplicationContext接口对应的refresh()方法。
这篇refresh的介绍是相对比较粗的内容,没有详细去拆解,因为我认为真的详细拆解了,可能看了 这边文章也记不住所以就大概介绍了下。
如果真的想把这里深入了解下,我的方式是通过代码打断点去看,一点点往下走,也不用一步步看,前面几次先看大概,后面再跟进自己感兴趣或者意向高的内容再去了解下,多跑断点,一点点就清晰了。后面会详细将跑断点的过程,先补充基础,在基础 上进行实操,这时候会有共鸣!