方法描述
refresh()是Spring最核心的方法,在springApplication.run(args)的时候执行,是一个同步同步方法,用synchronized关键字来实现。
org.springframework.context.support.AbstractApplicationContext#refresh
方法源码
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
StartupStep contextRefresh = this.applicationStartup.start("spring.context.refresh");
// Prepare this context for refreshing.
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// Prepare the bean factory for use in this context.
prepareBeanFactory(beanFactory);
try {
// Allows post-processing of the bean factory in context subclasses.
postProcessBeanFactory(beanFactory);
StartupStep beanPostProcess = this.applicationStartup.start("spring.context.beans.post-process");
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
beanPostProcess.end();
// Initialize message source for this context.
initMessageSource();
// Initialize event multicaster for this context.
initApplicationEventMulticaster();
// Initialize other special beans in specific context subclasses.
onRefresh();
// Check for listener beans and register them.
registerListeners();
// Instantiate all remaining (non-lazy-init) singletons.
finishBeanFactoryInitialization(beanFactory);
// Last step: publish corresponding event.
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.
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...
resetCommonCaches();
contextRefresh.end();
}
}
}
从源码中可以看出在refresh方法中包含13个子方法的调用
- prepareRefresh()
- obtainFreshBeanFactory()
- prepareBeanFactory(beanFactory)
- postProcessBeanFactory(beanFactory)
- invokeBeanFactoryPostProcessors(beanFactory)
- registerBeanPostProcessors(beanFactory)
- initMessageSource()
- initApplicationEventMulticaster()
- onRefresh()
- registerListeners()
- finishBeanFactoryInitialization(beanFactory)
- finishRefresh()
- resetCommonCaches()
refresh()13个子方法
1. prepareRefresh()
该方法用于容器状态设置,初始化属性设置,检查必备属性是否存在
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());
}
}
// 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<>();
}
- 设置必备属性,在启动的时候必须要配置
通过初始化器设置必备属性
@Order(0)
public class RequiredPropertiesInitializer implements ApplicationContextInitializer<ConfigurableApplicationContext> {
@Override
public void initialize(ConfigurableApplicationContext applicationContext) {
ConfigurableEnvironment environment = applicationContext.getEnvironment();
//设置启动的时候必须要silly属性值
environment.setRequiredProperties("silly");
}
}
启动加载初始化器
@SpringBootApplication
public class SpringBootDemoApplication {
public static void main(String[] args) {
// SpringApplication.run(SpringBootDemoApplication.class, args);
SpringApplication springApplication = new SpringApplication((SpringBootDemoApplication.class));
springApplication.addInitializers(new RequiredPropertiesInitializer());
springApplication.run(args);
}
}
启动SpringBoot结果
有启动的报错信息显示,必须设置刚刚在初始化中加的silly这个属性值,这时在application.yml中添加silly属性再次启动则正常启动
2. obtainFreshBeanFactory()
该方法主要设置beanFactory序列号id和获取beanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//设置beanFactory序列号id
refreshBeanFactory();
//获取beanFactory
return getBeanFactory();
}
这两个方法都是需要子类去实现
3. prepareBeanFactory(beanFactory)
该方法主要做一些设置工作,设置beanFactory一些属性、添加后置处理器、设置忽略的自动装配接口、设置 ClassLoader、设置 SpEL 表达式解析器,、加忽略注入的接口、注册一些组件
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 设置 beanFactory 的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
if (!shouldIgnoreSpel) {
// 设置支持表达式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
}
// 为 beanFactory 增加了一个默认的 propertyEditor ,这个主要是对 bean 的属性等设置管理的一个工具
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
// 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware等
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(ApplicationStartup.class);
// 注册可以解析的自动装配;我们能直接在任何组件中自动注入
beanFactory.registeresolvableDependency(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));
// 增加对 AspectJ 的支持
if (!IN_NATIVE_IMAGE && 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()));
}
// 环境信息ConfigurableEnvironment
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
// 系统属性,systemProperties【Map<String, Object>】
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
// 系统环境变量systemEnvironment【Map<String, Object>】
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. postProcessBeanFactory(beanFactory)
模板方法,子类重写已在BeanFactory完成创建后做进一步设置,比如环境下:在BeanFactory创建后添加一些web环境的作用域,环境配置信息,增加一些web环境的组件
StaticWebApplicationContext实现
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
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(beanFactory)
- 调用BeanDefinitionRegistryPostProcessor实现向容器内添加bean的定义
- 调用BeanFactoryPostProcessor实现向容器内bean的定义添加属性
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
在invokeBeanFactoryPostProcessors方法中,Spring 会先去找到所有的实现了BeanDefinitionRegistryPostProcessor的 BeanFactory 后置处理器,然后先执行实现PriorityOrdered的,再执行实现了Ordered的。
其中最著名的就是ConfigurationClassPostProcessor,用来扫描被 @Component 和 @Bean 标记的对象,并注册其 BeanDefinition 元数据到 Spring 容器的 BeanDefinitionMap 中。然后再去获取所有的 BeanFactory 后置处理器,去掉已经执行过的,也是根据排序依次执行。
该方法结束后,Spring 上下文中已经注册并执行了 BeanFactory 后置处理器,也将一部分 BeanDefinition 注册了进来
样例:实现BeanFactoryPostProcessor接口,设置bean属性
MyBeanFactoryPostprocessor.java 设置cat类name=MyBeanFactoryPostprocessor-cat
@Component
public class MyBeanFactoryPostprocessor implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
BeanDefinition cat = beanFactory.getBeanDefinition("cat");
MutablePropertyValues propertyValues = cat.getPropertyValues();
propertyValues.addPropertyValue("name", "MyBeanFactoryPostprocessor-cat");
}
}
单元测试打印结果
@RunWith(SpringRunner.class)
@SpringBootTest
@Import(MyCatImportRegistrar.class)
public class IocTest {
@Autowired
private Cat cat;
@Test
public void testBeanFactoryPostprocessor() {
System.out.println(cat.getName());
}
}
6. registerBeanPostProcessors(beanFactory)
该方法是注册 Bean 的后置处理器,找到BeanPostProcessor的实现,排序后注册进容器内
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
org.springframework.context.support.PostProcessorRegistrationDelegate#registerBeanPostProcessors(org.springframework.beans.factory.config.ConfigurableListableBeanFactory, org.springframework.context.support.AbstractApplicationContext)
// 1. 获取所有的 Bean 后置处理器的名字
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// 2. 对 Bean 后置处理器分类
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
// 3. 注册 Bean 后置处理器
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, orderedPostProcessors);
registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);
registerBeanPostProcessors(beanFactory, internalPostProcessors);
// 4. 注册 ApplicationListener 探测器
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
- priorityOrderedPostProcessors是所有实现了PriorityOrdered接口的后置处理器
- internalPostProcessors是所有内置的后置处理器
- orderedPostProcessorNames实现了ordered接口的后置处理器
- nonOrderedPostProcessorNames没有排序的后置处理器
7. initMessageSource()
初始化国际化相关属性
8. initApplicationEventMulticaster()
初始化事件广播器,并放入 applicationEventMulticaster bean 中
9. onRefresh()
模板方法,在容器刷新的时候可以自定义逻辑,不同的Spring容器做不同的事情,比如:web环境中, 创建web容器
10. registerListeners()
添加容器内事件监听器至事件广播器中,派发早期事件
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);
}
}
}
11. finishBeanFactoryInitialization(beanFactory)
实例化所有剩余的非懒加载单例,比如invokeBeanFactoryPostProcessors方法中根据各种注解解析出来的类,在这个时候都会被初始化。实例化的过程各种BeanPostProcessor开始起作用
// 1. 冻结所有的 bean,已经注册的 bean 定义将不会被修改或任何进一步的处理
beanFactory.freezeConfiguration();
// 2. 实例化所有剩余的非懒加载的 bean
beanFactory.preInstantiateSingletons();
// 3.获取容器中所有 beanDefinition 的名称
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
for (String beanName : beanNames) {
// 根据 beanName 获取 BeanDefinition
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
// 不是抽象的 && 是单例的 && 不是懒加载的
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
// 如果是 FactoryBean,就先获取 FactoryBean 实例
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
xxx 实现
}
}
else {
// 如果不是 FactoryBean,就直接获取 Bean
getBean(beanName);
}
}
}
12. finishRefresh()
初始化生命周期处理器,调用生命周期处理器onRefresh方法,发布ContextRefreshedEvent事件,JMX相关处理
// 清除上下文资源缓存(如扫描中的ASM元数据) scanning).
clearResourceCaches();
// 初始化上下文的生命周期处理器,并刷新(找出Spring容器中实现了Lifecycle接口的bean并执行start()方法)
initLifecycleProcessor();
getLifecycleProcessor().onRefresh();
// 发布ContextRefreshedEvent事件告知对应的ApplicationListener进行响应的操作
publishEvent(new ContextRefreshedEvent(this));
13. resetCommonCaches()
清空产生的缓存数据
protected void resetCommonCaches() {
ReflectionUtils.clearCache();
AnnotationUtils.clearCache();
ResolvableType.clearCache();
CachedIntrospectionResults.clearClassLoader(getClassLoader());
}
Bean实例化过程
由finishBeanFactoryInitialization来实现Bean实例化过程