容器刷新
在构造方法的初始以及配置类的注册中,大多BeanPostProcessor都只是生成了BeanDefinition,还没有完成实例化,但在AbstractApplicationContext的refresh()方法中,会进行一系列的初始化,以及对这些BeanPostProcessor进行排序。除了进行初始化之外,还会去设置一些EL表达式解析器、类型转化注册器等。
1、 刷新前工作
在构造方法中,Spring容器里面只是设置了操作系统的环境变量和JVM的环境变量,对于Web类型的Spring容器,还必须要包括Servlet中设置的参数,而刷新前的工作,主要就是去加载AbstractApplicationContext子类的一些参数,比如GenericWebApplicationContext中,会去加载Servlet上下文的参数
protected void prepareRefresh() {
// Switch to active.
this.startupDate = System.currentTimeMillis();
//设置容器运行状态
this.closed.set(false);
this.active.set(true);
// Initialize any placeholder property sources in the context environment.
// 比如子类可以把ServletContext中的参数对设置到Environment
initPropertySources();
// Validate that all properties marked as required are resolvable:
// see ConfigurablePropertyResolver#setRequiredProperties
getEnvironment().validateRequiredProperties();
……
}
2 、容器重复刷新
在Spring容器刷新时,会判断容器是否允许重复刷新,如果允许重复刷新,且当前容器已经有了BeanFactory对象,则需要销毁BeanFactory单例池中所有的Bean实例,然后重新生成一个新的DefaultListableBeanFactory对象作为beanFactory;如果不允许重复刷新,重复刷新将会抛异常。
只有实现了AbstractRefreshableWebApplicationContext类的Spring重启,才允许重复刷新容器
调用obtainFreshBeanFactory()返回已有的beanFactory或重新生成一个beanFactory
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
AbstractRefreshableWebApplicationContext的refreshBeanFactory()会去销毁单例池中的Bean实例,然后生成新的BeanFactory并初始化,而
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
AbstractRefreshableWebApplicationContext类中方法:
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
DefaultListableBeanFactory beanFactory = createBeanFactory();
beanFactory.setSerializationId(getId());
customizeBeanFactory(beanFactory);
loadBeanDefinitions(beanFactory);
this.beanFactory = beanFactory;
}
}
GenericApplicationContext类中方法:
protected final void refreshBeanFactory() throws IllegalStateException {
if (!this.refreshed.compareAndSet(false, true)) {
throw new IllegalStateException(
"GenericApplicationContext does not support multiple refresh attempts: just call 'refresh' once");
}
this.beanFactory.setSerializationId(getId());
}
3、 准备BeanFactory
在第三步会去设置一些BeanFactory的基本属性,包括类加载器、SpringEL表达式解析器以及类型转换注册器
beanFactory.setBeanClassLoader(getClassLoader());
// Spring5.3中新增的功能,可以选择是否开启Spel功能,shouldIgnoreSpel默认为false,表示开启
if (!shouldIgnoreSpel) {
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 添加一个ResourceEditorRegistrar,注册一些级别的类型转化器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
添加三个BeanProcessor的实例对象,分别是ApplicationContextAwareProcessor、ApplicationListenerDetector和LoadTimeWeaverAwareProcessor
// Configure the bean factory with context callbacks.
// 组成一个BeanPostProcessor,用来处理EnvironmentAware、EmbeddedValueResolverAware等回调
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// Register early post-processor for detecting inner beans as ApplicationListeners.
// ApplicationListenerDetector负责把ApplicantsListener类型的Bean注册到ApplicationContext中
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// Aspectj本身是通过编译期进行代理的,在Spring中就跟LoadTimeWeaver有关
if (!NativeDetector.inNativeImage() && 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()));
}
同时设置回调接口的方法不进行自动注入,并注册当前容器的依赖关系到ResolvableDependency,最后注册三个与环境变量相关的bean以及一个应用启动的实例到单例池中
// 如果一个属性对应的set方法在ignoredDependencyInterfaces接口中被定义了,则该属性不会进行自动注入(是Spring中的自动注入,不是@Autowired)
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.ignoreDependencyInterface(ApplicationStartupAware.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 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());
}
if (!beanFactory.containsLocalBean(APPLICATION_STARTUP_BEAN_NAME)) {
beanFactory.registerSingleton(APPLICATION_STARTUP_BEAN_NAME, getApplicationStartup());
}
4、 子类设置BeanFactory
上一步,主要设置了BeanFactory公有的一些属性,但对于AbstractApplicationContext其子类来说,可能还需要一些特有的属性,以GenericWebApplicationContext为例,还要设置一些与servletContext相关的属性
// 子类来设置一下BeanFactory
postProcessBeanFactory(beanFactory);
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
5、 执行BeanFactoryPostProcessor方法
BeanFactory准备好了之后,执行BeanFactoryPostProcessor,开始对BeanFactory进行处理,默认情况下,此时beanFactory的BeanDefinitionMap中有6个BeanDefinition,其中5个都是在前面构造创建时添加进来的,还有一个注册配置类时添加的配置类AppConfig的BeanDefinition,而这6个中只有一个BeanFactoryPostProcessor:ConfigurationClassPostProcessor
这里会执行ConfigurationClassPostProcessor进行@Component的扫描,扫描得到BeanDefinition,并注册到beanFactory中
// 注意:扫描的过程中可能又会扫描出其他的BeanFactoryPostProcessor,那么这些BeanFactoryPostProcessor也得在这一步执行
invokeBeanFactoryPostProcessors(beanFactory); // scanner.scan()
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)
// 关于LoadTimeWeaver看这篇文章了解即可,https://www.cnblogs.com/wade-luffy/p/6073702.html
if (!NativeDetector.inNativeImage() && beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
6、 实例化BeanPostProcessors
在上一步执行BeanFactoryPostProcessor的方法进行扫描,会将扫描到的所有实现了BeanPostProcessor的类生成BeanDefinition,而这些BeanPostProcessor的实例在创建Bean实例时都会用到,所以,这一步主要是将所有的BeanPostProcessor进行实例化,并排序,然后添加到BeanFactory的beanPostProcessors属性中去
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
注:关于invokeBeanFactoryPostProcessors()和registerBeanPostProcessors()的介绍,将会在后面下一篇文章着重介绍
7、 初始化MessageSource
设置ApplicationContext的MessageSource,要么是用户设置的,要么是DelegatingMessageSource,主要用于处理国际化资源
// Initialize message source for this context.
initMessageSource();
如果当前beanFactory还没有MessageSource,则生成一个DelegatingMessageSource对象,并设置父messageSource,最后将MessageSource实例添加到beanFactory的单例池中
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.
// 拿父ApplicationContext的messageSource作为this.messageSource的父messageSource
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
}
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);
}
}
8、 初始化事件广播器
事件广播器主要是当发布事件时,获取所有的事件监听器,来串行或并行处理发布的事件
// Initialize event multicaster for this context.
// 设置ApplicationContext的applicationEventMulticaster,么是用户设置的,要么是SimpleApplicationEventMulticaster
initApplicationEventMulticaster();
如果存在名字为“applicationEventMulticaster”的BeanDefinition,则直接根据BeanDefinition生成一个ApplicationEventMulticaster实例;如果没有BeanDefinition,则直接生成一个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);
}
else {
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(beanFactory);
beanFactory.registerSingleton(APPLICATION_EVENT_MULTICASTER_BEAN_NAME, this.applicationEventMulticaster);
}
}
9、 注册事件监听器
// Check for listener beans and register them.
// 把定义的ApplicationListener的Bean对象,设置到ApplicationContext中去,并执行在此之前所发布的事件
registerListeners();
将所有的ApplicationListener实例添加到当前容器的事件广播器ApplicationEventMulticaster,同时找到所有ApplicationListener实现类的BeanName也添加到事件广播器中,主要为了应对懒加载的事件监听器
最后去处理事件广播器初始化之前发布的事件
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...
// 添加了事件监听器后,判断是否有earlyApplicationEvents,如果有就使用事件广播器发布earlyApplicationEvents
// earlyApplicationEvents表示在事件广播器还没生成好之前ApplicationContext所发布的事件
Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents;
this.earlyApplicationEvents = null;
if (!CollectionUtils.isEmpty(earlyEventsToProcess)) {
for (ApplicationEvent earlyEvent : earlyEventsToProcess) {
getApplicationEventMulticaster().multicastEvent(earlyEvent);
}
}
}
发布-监听事件的大概流程:容器调用publishEvent()来发布事件,然后该容器的事件广播器将遍历它的事件监听器,并行或串行来执行事件监听器方法
10、 完成BeanFactory初始化
这一步其中最重要的就是实例化非懒加载的单例Bean,但是也还有一些其他的操作,比如:设置类型转换器、默认的占位符解析器
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
// 如果BeanFactory中存在名字叫conversionService的Bean,则设置为BeanFactory的conversionService属性
// 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));
}
// 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.
// 设置默认的占位符解析器 ${xxx} ---key
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);
}
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化非懒加载的单例Bean
beanFactory.preInstantiateSingletons();
}
11、 完成刷新,发布事件
// Last step: publish corresponding event.
finishRefresh();
在最后完成刷新这一步,会去设置lifecycleProcessor,并调用onRefresh()去更新容器的状态,后面容器状态的改变都会调用lifecycleProcessor的内部方法类更新状态,最后发布一个容器启动完成的事件
protected void finishRefresh() {
// Clear context-level resource caches (such as ASM metadata from scanning).
clearResourceCaches();
// Initialize lifecycle processor for this context.
// 设置lifecycleProcessor,默认为DefaultLifecycleProcessor
initLifecycleProcessor();
// Propagate refresh to lifecycle processor first.
// 调用LifecycleBean的start()
getLifecycleProcessor().onRefresh();
// Publish the final event.
publishEvent(new ContextRefreshedEvent(this));
}