文章目录
refresh()方法是Spring容器启动的核心中的核心,逻辑也是异常的复杂,因为准备分两篇文章来叙述他的过程,以及源码的分析
Spring Bean声明周期流程图
Spring Bean的完整生命周期从创建Spring容器开始,直到最终Spring容器销毁Bean,这其中包含了一系列关键点。
简单分类如下:
- 工厂后置处理器(BeanFactoryPostProcessor):这个包括了AspectJWeavingEnabler, ConfigurationClassPostProcessor, CustomAutowireConfigurer等等非常有用的工厂后处理器 接口的方法。工厂后处理器也是容器级的。
- 容器级别生命周期处理器:包括了InstantiationAwareBeanPostProcessor 和 BeanPostProcessor 这两个接口实现,一般称它们的实现类为“后处理器”
- Bean级生命周期接口方法(仅作用于某个Bean):这个包括了BeanNameAware、BeanFactoryAware、InitializingBean和DiposableBean这些接口的方法
- Bean自身的方法:这个包括了Bean本身调用的方法和通过配置文件中
<bean>
的init-method和destroy-method指定的方法
因为我们项目的案例是全注解驱动的,因此我们的容器实例为:AnnotationConfigWebApplicationContext(若你是xml配置驱动,则为XmlWebApplicationContext)
refresh()方法所有的ApplicationContext子类都没重写,只有AbstractApplicationContext里有实现过(接口定义在ConfigurableApplicationContext)
AbstractApplicationContext#refresh()
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
//容器刷新前的准备,设置上下文状态,获取属性,验证必要的属性等
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 获取新的beanFactory,销毁原有beanFactory、为每个bean生成BeanDefinition等
// 注意,此处是获取新的,销毁旧的,这就是刷新的意义
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
//配置标准的beanFactory,设置ClassLoader,设置SpEL表达式解析器等
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
//模板方法,允许在子类中对beanFactory进行后置处理。
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
//实例化并调用所有注册的beanFactory后置处理器(实现接口BeanFactoryPostProcessor的bean)。
//在beanFactory标准初始化之后执行 例如:PropertyPlaceholderConfigurer(处理占位符)
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
//实例化和注册beanFactory中扩展了BeanPostProcessor的bean。
//例如:
//AutowiredAnnotationBeanPostProcessor(处理被@Autowired注解修饰的bean并注入)
//RequiredAnnotationBeanPostProcessor(处理被@Required注解修饰的方法)
//CommonAnnotationBeanPostProcessor(处理@PreDestroy、@PostConstruct、@Resource等多个注解的作用)等。
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
//初始化国际化工具类MessageSource
initMessageSource();
// Initialize event multicaster for this context.
//初始化事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
//模板方法,在容器刷新的时候可以自定义逻辑(子类自己去实现逻辑),不同的Spring容器做不同的事情
onRefresh();
// Check for listener beans and register them.
//注册监听器,并且广播early application events,也就是早期的事件
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
//非常重要。。。实例化所有剩余的(非懒加载)单例Bean。(也就是我们自己定义的那些Bean们)
//比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化 扫描的 @Bean之类的
//实例化的过程各种BeanPostProcessor开始起作用
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
//refresh做完之后需要做的其他事情
//清除上下文资源缓存(如扫描中的ASM元数据)
//初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)。
//发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
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.
//如果刷新失败那么就会将已经创建好的单例Bean销毁掉
destroyBeans();
// Reset 'active' flag.
//重置context的活动状态 告知是失败的
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内核的缓存。因为可能不再需要metadata给单例Bean了。
resetCommonCaches();
}
}
}
AbstractApplicationContext#prepareRefresh()
protected void prepareRefresh() {
//记录容器启动时间,然后设立对应的标志位
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// 打印info日志:开始刷新this此容器了
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
// 这是扩展方法,由子类去实现,可以在验证之前为系统属性设置一些值可以在子类中实现此方法
// 因为我们这边是AnnotationConfigApplicationContext,可以看到不管父类还是自己,都什么都没做,所以此处先忽略
initPropertySources();
// Validate that all properties marked as required are resolvable
// see ConfigurablePropertyResolver#setRequiredProperties
//这里有两步,getEnvironment(),然后是是验证是否系统环境中有RequiredProperties参数值 如下详情
// 然后管理Environment#validateRequiredProperties 后面在讲到环境的时候再专门讲解吧
// 这里其实就干了一件事,验证是否存在需要的属性
getEnvironment().validateRequiredProperties();
// Allow for the collection of early ApplicationEvents,
// to be published once the multicaster is available...
// 初始化容器,用于装载早期的一些事件
this.earlyApplicationEvents = new LinkedHashSet<>();
}
AbstractApplicationContext#getEnvironment()
实现了接口EnvironmentCapable的getEnvironment()方法
@Override
public ConfigurableEnvironment getEnvironment() {
if (this.environment == null) {
this.environment = createEnvironment();
}
return this.environment;
}