方法描述

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个子方法的调用

  1. prepareRefresh()
  2. obtainFreshBeanFactory()
  3. prepareBeanFactory(beanFactory)
  4. postProcessBeanFactory(beanFactory)
  5. invokeBeanFactoryPostProcessors(beanFactory)
  6. registerBeanPostProcessors(beanFactory)
  7. initMessageSource()
  8. initApplicationEventMulticaster()
  9. onRefresh()
  10. registerListeners()
  11. finishBeanFactoryInitialization(beanFactory)
  12. finishRefresh()
  13. 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));
  1. priorityOrderedPostProcessors是所有实现了PriorityOrdered接口的后置处理器
  2. internalPostProcessors是所有内置的后置处理器
  3. orderedPostProcessorNames实现了ordered接口的后置处理器
  4. 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实例化过程
在这里插入图片描述

Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐