实验环境:spring-framework-5.0.2、jdk8、gradle4.3.1
- Spring源码-IOC部分-容器简介【1】
- Spring源码-IOC部分-容器初始化过程【2】
- Spring源码-IOC部分-Xml Bean解析注册过程【3】
- Spring源码-IOC部分-自定义IOC容器及Bean解析注册【4】
- Spring源码-IOC部分-Bean实例化过程【5】
- Spring源码-IOC部分-Spring是如何解决Bean循环依赖的【6】
容器的初始化过程主要通过AbstractApplicationContext的refresh()方法来完成,其主要步骤如下
AbstractApplicationContext#refresh()方法
refresh方法
/**
* refresh方法的主要作用是:在创建IoC容器前,如果已经有容器存在,需要把已有的容器销毁和关闭,
* 以保证在refresh方法之后使用的是新创建的IoC容器。
* 它类似于对IoC容器的重启,在新创建的容器中对容器进行初始化,对Bean配置资源进行载入。
*/
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 1、准备刷新,获取当前时间,给容器设置同步表识
prepareRefresh();
// 2、子类刷新并初始化BeanFactory,在这一步生成beanFactory实例(DefaultListableBeanFactory),
// 在这里完成BeanDefinition的加载(loadBeanDefinitions)
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 3、初始化beanFactory,设置容器特性,例如类加载器、事件处理器等
prepareBeanFactory(beanFactory);
try {
// 4、空方法,bean实例化之前执行。容器子类可以对beanFactory做一些操作
postProcessBeanFactory(beanFactory);
// 5、bean实例化之前执行。用户可以继承BeanFactoryPostProcessors接口,在这一步对beanFactory做一些操作
invokeBeanFactoryPostProcessors(beanFactory);
// 6、BeanPostProcessors是bean的后置处理器,用于监听容器触发的事件。
// 在bean实例化之后,init-method方法前后执行
// 用户可以继承BeanPostProcessors接口,在这一步对bean方法进行修改,具体执行在step12之后,这一步只是先注册上
registerBeanPostProcessors(beanFactory);
// 7、初始化信息源,和国际化相关
initMessageSource();
// 8、初始化事件传播器
initApplicationEventMulticaster();
// 9、空方法,容器子类可以在这一步进行操作
onRefresh();
// 10、为事件传播器,注册事件监听器
registerListeners();
// 11、【重要】实例化所有剩余的非懒加载单例bean,在这一步完成bean的实例化
finishBeanFactoryInitialization(beanFactory);
// 12、初始化容器的生命周期事件处理器,并且发布容器的生命周期事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
// 销毁bean
destroyBeans();
// 取消刷新,重置active标示
cancelRefresh(ex);
// Propagate exception to caller.
throw ex;
}
finally {
// 清空缓存
resetCommonCaches();
}
}
}
1、prepareRefresh方法
prepareRefresh方法
/**
* 准备刷新上下文,设置启动日期和活动标志、属性源的初始化。
*/
protected void prepareRefresh() {
// 设置启动时间
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// 初始化上下文环境中的任何占位符属性源(空方法,交给子类实现)
initPropertySources();
// 创建并获取环境对象,验证所有标记为必需的属性是否可解析
// 参考 ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
// 初始化earlyApplicationEvents,在multicaster可用后发布
this.earlyApplicationEvents = new LinkedHashSet<>();
}
2、obtainFreshBeanFactory方法:在这一步创建了beanFactory实例,并且进行了bean资源的加载
obtainFreshBeanFactory方法
/**
* 初始化BeanFactory,在这一步完成了loadBeanDefinitions的加载
*/
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
// 抽象方法,交给子类实现。
// 子类刷新beanFactory,比如子类AbstractRefreshableApplicationContext会在refreshBeanFactory方法里createBeanFactory,并且执行loadBeanDefinitions加载资源配置。
// 而GenericApplicationContext只会对已经创建好的beanFactory实例设置一下id即可,loadBeanDefinitions放在了外部去做。
refreshBeanFactory();
// getBeanFactory也是抽象方法,由子类创建beanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
比如子类AbstractRefreshableApplicationContext对其实现的refreshBeanFactory、getBeanFactory方法如下
refreshBeanFactory方法
/**
* 刷新BeanFactory,实现父类AbstractApplicationContext的抽象方法
*/
@Override
protected final void refreshBeanFactory() throws BeansException {
// 如果已经存在BeanFactory,销毁容器里的bean,关闭BeanFactory
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 创建beanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
// 对IOC容器进行定制化,如设置启动参数、开启注解对自动装配等
customizeBeanFactory(beanFactory);
// 调用载入bean定义对方法,loadBeanDefinitions(beanFactory)在本类是个抽象方法,交给子类实现
loadBeanDefinitions(beanFactory);
// 加锁,写的时候不允许读写
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
protected DefaultListableBeanFactory createBeanFactory() {
return new DefaultListableBeanFactory(getInternalParentBeanFactory());
}
@Override
public final ConfigurableListableBeanFactory getBeanFactory() {
// 加锁,读的时候不允许写
synchronized (this.beanFactoryMonitor) {
if (this.beanFactory == null) {
throw new IllegalStateException("BeanFactory not initialized or already closed - " +
"call 'refresh' before accessing beans via the ApplicationContext");
}
return this.beanFactory;
}
}
3、prepareBeanFactory方法:对beanFactory做一些初始化的工作,设置一些默认属性
prepareBeanFactory方法
/**
* 为BeanFactory设置一些初始化的属性值,例如上下文的类加载器和后处理器。
*/
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
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);
// BeanFactory interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a 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.
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());
}
}
4、postProcessBeanFactory方法
查看代码
/**
* 根据上下文的标准修改其内部bean工厂初始化。所有bean定义都已加载,但没有bean将被实例化。
* 这允许注册特殊的BeanPostProcessors等在某些ApplicationContext实现中。
*/
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
}
比如子类AbstractRefreshableWebApplicationContext对其实现如下
查看代码
/**
* 注册request/session作用域
*/
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 添加Servlet容器相关的后置处理器
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
beanFactory.ignoreDependencyInterface(ServletConfigAware.class);
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext, this.servletConfig);
}
5、invokeBeanFactoryPostProcessors方法:在这一步对BeanDefinition进行增强(相关修改操作)
invokeBeanFactoryPostProcessors方法
/**
* BeanFactoryPostProcessor是在spring容器加载了beanDefinition之后,在bean实例化之前执行的。
* 实现BeanFactoryPostProcessor接口,可以在bean实例化之前修改beanDefinition相关配置。
* 可以同时配置多个BeanFactoryPostProcessor,并通过设置'order'属性来控制各个BeanFactoryPostProcessor的执行次序。
*/
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 检测LoadTimeWeaver并准备编织(如果同时发现)(例如,通过ConfigurationClassPostProcessor注册的@Bean方法)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
6、registerBeanPostProcessors方法
查看代码
/**
* BeanPostProcessor,可以在spring容器实例化bean之后,在执行bean的初始化方法前后,添加一些自己的处理逻辑。
*/
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
7、initMessageSource方法
查看代码
/**
* Initialize the MessageSource.
* Use parent's if none defined in this context.
*/
protected void initMessageSource() {
// 这里获取的beanFactory和refresh里obtainFreshBeanFactory获取的是同一个,
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.isDebugEnabled()) {
logger.debug("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.isDebugEnabled()) {
logger.debug("Unable to locate MessageSource with name '" + MESSAGE_SOURCE_BEAN_NAME +
"': using default [" + this.messageSource + "]");
}
}
}
8、initApplicationEventMulticaster方法
查看代码
/**
* spring中是通过ApplicationListener及ApplicationEventMulticaster来进行事件驱动开发的,即实现观察者设计模式或发布-订阅模式。
* ApplicationListener监听容器中发布的事件,只要事件发生,就触发监听器的回调,来完成事件驱动开发。属于观察者设计模式中的Observer对象。
* ApplicationEventMulticaster用来通知所有的观察者对象,属于观察者设计模式中的Subject对象。
*/
protected void initApplicationEventMulticaster() {
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
// 判断容器中是否存在applicationEventMulticaster
// 也就是自定义的事件监听多路广播器,必须实现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 {
// 如果没有,则默认采用SimpleApplicationEventMulticaster
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 + "]");
}
}
}
9、onRefresh方法
查看代码
/**
* 模板方法,可以重写该方法以添加特定于上下文的刷新工作。
* 在初始化特殊bean时调用,然后实例化单例。
*/
protected void onRefresh() throws BeansException {
// For subclasses: do nothing by default.
}
10、registerListeners方法
查看代码
/**
* 添加实现ApplicationListener的bean作为监听器。
* 不会影响其他监听器,可以添加这些监听器而无需添加bean。
*/
protected void registerListeners() {
// 首先注册静态指定的监听器
for (ApplicationListener> listener : getApplicationListeners()) {
getApplicationEventMulticaster().addApplicationListener(listener);
}
// 不要在这里初始化FactoryBean:我们需要保留所有常规Bean,未初始化以允许后处理器应用于它们!
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
// 发布早期应用程序事件现在我们终于有了一个multicaster
Set earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (earlyEventsToProcess != null) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
11、 finishBeanFactoryInitialization 详情见Spring源码-IOC部分-Bean实例化过程【5】
查看代码
/**
* 完成此上下文的bean工厂的初始化,初始化所有剩余的单例bean。
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 1.初始化此上下文的转换服务
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));
}
// 2.如果beanFactory之前没有注册嵌入值解析器,则注册默认的嵌入值解析器:主要用于注解属性值的解析。
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 3.初始化LoadTimeWeaverAware Bean实例对象
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class,
false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
// 4.冻结所有bean定义,注册的bean定义不会被修改或进一步后处理,因为马上要创建 Bean 实例对象了
beanFactory.freezeConfiguration();
// 5.实例化所有剩余(非懒加载)单例对象 (这一步很重要,bean的实例化是从这里开始的)
beanFactory.preInstantiateSingletons();
}
12、finishRefresh方法
查看代码
/**
* 完成刷新工作
* 调用LifecycleProcessor的onRefresh方法并发布
*/
protected void finishRefresh() {
// 清除上下文级别的资源缓存(例如来自扫描的ASM元数据)。
clearResourceCaches();
// 为此上下文初始化lifecycle processor。
initLifecycleProcessor();
// 首先将刷新传播到lifecycle processor。
getLifecycleProcessor().onRefresh();
// 发布事件
publishEvent(new ContextRefreshedEvent(this));
// 如果active,请参与LiveBeansView MBean。
LiveBeansView.registerApplicationContext(this);
}
参考资料:
《Spring5核心原理与30个类手写》作者 谭勇德
《Spring源码深度解析》作者 郝佳
《Spring技术内幕》作者 计文柯