前言
这一节,我们来看一下 Spring 启动的核心方法 -- refresh 方法。
refresh 方法,是 Spring Bean 配置读取加载入口,也是 Spring 框架的启动流程。
refresh 方法
refresh 方法概览
我们还是从 SpringApplication.run(String... args)
看起。
// SpringApplication # run(String... args) # 311-313
public ConfigurableApplicationContext run(String... args) {
// …………
prepareContext(context, environment, listeners, applicationArguments, printedBanner);
refreshContext(context);
afterRefresh(context, applicationArguments);
// …………
return context;
}
我们进入 refreshContext(context)
方法体中:
// SpringApplication # refreshContext(ConfigurableApplicationContext context) # 390
private void refreshContext(ConfigurableApplicationContext context) {
refresh(context);
if (this.registerShutdownHook) {
try {
context.registerShutdownHook();
}
catch (AccessControlException ex) {
// Not allowed in some environments.
}
}
}
很显然,核心方法还是去调用了 refresh(context):
// SpringApplication # refresh(ApplicationContext applicationContext) # 742
protected void refresh(ApplicationContext applicationContext) {
Assert.isInstanceOf(AbstractApplicationContext.class, applicationContext);
((AbstractApplicationContext) applicationContext).refresh();
}
继续进入((AbstractApplicationContext) applicationContext).refresh()
:
// AbstractApplicationContext # refresh() # 515
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// Prepare this context for refreshing.
// 为刷新容器,准备上下文
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
// 告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
// 准备在此上下文使用的bean工厂。
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
// 允许在上下文子类中对bean工厂进行后处理
postProcessBeanFactory(beanFactory);
// Invoke factory processors registered as beans in the context.
// 调用在上下文中注册为bean的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
// 注册拦截Bean创建的Bean处理器。
registerBeanPostProcessors(beanFactory);
// Initialize message source for this context.
// 初始化此上下文的消息源。
initMessageSource();
// Initialize event multicaster for this context.
// 为上下文,初始化事件广播器
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
// 在特定上下文子类中初始化其他特殊bean。
onRefresh();
// Check for listener beans and register them.
// 检查监听器并注册。
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
// 实例化所有剩余的(非延迟初始化)单例。
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
// 发布相应的事件。
finishRefresh();
}
// …………
}
prepareRefresh
方法注释:准备此上下文以进行刷新,设置其启动日期和活动标志以及执行属性源的任何初始化。
protected void prepareRefresh() {
// 设置启动日期、活动标志
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
// …………
// Initialize any placeholder property sources in the context environment.
// 初始化属性设置
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
// AbstractApplicationContext # obtainFreshBeanFactory() # 635
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
return getBeanFactory();
}
这个方法比较简单,做了两件事:
- 设置 beanFactory 的序列化 id
- 获取 beanFacotory
prepareBeanFactory
此方法,主要设置 从obtainFreshBeanFactory()
获取到的 beanFacotory
的各种属性。
方法注释:配置工厂的标准上下文特征,例如上下文的ClassLoader和后处理器
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Tell the internal bean factory to use the context's class loader etc.
// 告诉内部bean工厂使用上下文的类加载器等。
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
// 使用上下文回调配置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.
// BeanFactory接口未在普通工厂中注册为可解析类型。
// MessageSource registered (and found for autowiring) as a bean.
// MessageSource注册为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检测为ApplicationListeners。
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
// 检测LoadTimeWeaver,并准备进行织入(如果找到)。
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
// Set a temporary ClassLoader for type matching.
// 设置一个临时的ClassLoader以进行类型匹配。
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
// Register default environment beans.
// 注册默认环境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());
}
}
此方法,做了以下几件事:
- 设置 beanFactory 的一些属性
- 添加后置处理器
- 设置忽略的自动装配接口
- 注册一些组件
postProcessBeanFactory(beanFactory)
这里是一个空实现,留给子类重写。可以在 beanFactory 完成创建后做进一步设置。
对于 Servlet 而言,就是设置一些作用域之类的,例如 request、session 等。
invokeBeanFactoryPostProcessors(beanFactory)
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()));
}
}
这里的主要逻辑在 invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors())
:
这个方法体太长了,就不贴出来了。主要做了两件事:
-
调用
BeanDefinitionRegistryPostProcessor
实现向容器内添加bean的定义。其实这里我们在上一小节实践过了,下面就是我们添加的 Bean 。
@Componentpublic class MyBeanDefinitionRegistryPostProcessor implements BeanDefinitionRegistryPostProcessor { @Override public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException { RootBeanDefinition rootBeanDefinition = new RootBeanDefinition(); rootBeanDefinition.setBeanClass(MyTwoBean.class); beanDefinitionRegistry.registerBeanDefinition("myTwoBean",rootBeanDefinition); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { }}
-
调用
BeanFactoryPostProcessor
实现向容器内添加bean的定义添加属性。
registerBeanPostProcessors(beanFactory)
这个方法和invokeBeanFactoryPostProcessors(beanFactory)
是类似的。
找到BeanPostPocessor的实现,排序后注册进容器内。
initMessageSource()
主要是国际化、多语言配置。
不是重点,略过。
initApplicationEventMulticaster()
初始化事件广播器。监听器相关内容,我们之前已经学习过。此处也是类似的。
// 当前有监听器就用监听器;没有的话,就新建一个。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); } }
onRefresh()
子类实现。Servlet 下主要表现为创建 web 容器。
// ServletWebServerApplicationContext # onRefresh() # 150protected void onRefresh() { super.onRefresh(); try { createWebServer(); } catch (Throwable ex) { throw new ApplicationContextException("Unable to start web server", ex); } }
我们知道super.onRefresh()
是空实现,所以直接看createWebServer()
:
// 这个方法就是:创建容器的方法。我们暂不深究。private void createWebServer() { WebServer webServer = this.webServer; ServletContext servletContext = getServletContext(); if (webServer == null && servletContext == null) { ServletWebServerFactory factory = getWebServerFactory(); this.webServer = factory.getWebServer(getSelfInitializer()); } else if (servletContext != null) { try { getSelfInitializer().onStartup(servletContext); } catch (ServletException ex) { throw new ApplicationContextException("Cannot initialize servlet context", ex); } } initPropertySources(); }
registerListeners()
protected void registerListeners() { // Register statically specified listeners first. // 首先注册静态指定的侦听器。 for (ApplicationListener<?> listener : getApplicationListeners()) { getApplicationEventMulticaster().addApplicationListener(listener); } // 把容器中 listenerBean 注册 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... // 当Bean没加载完时,事件是发布不出去的,所以暂时保存在earlyApplicationEvents中 // 到此时,再把攒下的事件发布出去。 Set<ApplicationEvent> earlyEventsToProcess = this.earlyApplicationEvents; this.earlyApplicationEvents = null; if (earlyEventsToProcess != null) { for (ApplicationEvent earlyEvent : earlyEventsToProcess) { getApplicationEventMulticaster().multicastEvent(earlyEvent); } } }
finishBeanFactoryInitialization(beanFactory)
实例化BeanFactory 中已经被注册但是没被实例化的所有实例。
这是比较重要的 Bean 实例化流程。所以我们后面单开一节来学习。
所以,暂时不过多探究源码了。
finishRefresh()
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. // 生命周期处理器的 onRefresh() ,也是非学习重点。 getLifecycleProcessor().onRefresh(); // Publish the final event. // 发布容器已刷新事件 publishEvent(new ContextRefreshedEvent(this)); // Participate in LiveBeansView MBean, if active. // 非学习重点。 LiveBeansView.registerApplicationContext(this);}
resetCommonCaches()
此方法在 finally {} 中被调用,做一些清除缓存的工作。
protected void resetCommonCaches() { ReflectionUtils.clearCache(); AnnotationUtils.clearCache(); ResolvableType.clearCache(); CachedIntrospectionResults.clearClassLoader(getClassLoader()); }
总结
至此,refresh 方法我们已经过了一遍。
这一小节,还是着重于 refresh 的总体流程。对于一些细节,留待以后慢慢学习,一口又吃不成个大胖子。