下面是关于“Spring IoC学习之ApplicationContext中refresh过程详解”的完整攻略。
前言
在使用Spring
框架时,我们经常会用到ApplicationContext
容器,并在容器初始化时调用refresh()
方法来启动容器。那么这个过程中都做了些什么呢?本文将详细解析ApplicationContext
容器的refresh()
过程,帮助读者更好的理解Spring
框架中实例化、属性注入、AOP、事务管理等方面的知识点。
refresh()方法概述
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
...
@Override
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
// 准备刷新容器
prepareRefresh();
// 准备Bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 设置Bean工厂的类加载器、后置处理器、属性编辑器等
prepareBeanFactory(beanFactory);
try {
// 支持子类覆盖的方法,用于加载Bean定义,装配Bean组件
postProcessBeanFactory(beanFactory);
// 实例化并注入非懒加载的单例Bean对象
invokeBeanFactoryPostProcessors(beanFactory);
// 注册Bean后置处理器,通常用于Bean初始化前后的扩展操作
registerBeanPostProcessors(beanFactory);
// 初始化剩余非懒加载的Bean对象
initMessageSource();
// 初始化资源查找器
initApplicationEventMulticaster();
// 预留用于子类的扩展点,留待子类自行实现
onRefresh();
// 注册应用中的事件监听器
registerListeners();
// 实例化并初始化剩余的单例Bean对象
finishBeanFactoryInitialization(beanFactory);
// 完成刷新过程,通常包括清除缓存和发布容器生命周期事件
finishRefresh();
}
catch (BeansException | RuntimeException ex) {
destroyBeans();
cancelRefresh(ex);
throw ex;
}
}
}
...
}
从上面的源码中可以看到refresh()
方法的整个执行过程,可以分为以下几个步骤:
- 准备刷新容器。
- 准备
Bean
工厂。 - 设置
Bean
工厂的类加载器、后置处理器、属性编辑器等。 - 支持子类覆盖的方法,用于加载
Bean
定义,装配Bean
组件。 - 实例化并注入非懒加载的单例
Bean
对象。 - 注册
Bean
后置处理器,通常用于Bean
初始化前后的扩展操作。 - 初始化剩余非懒加载的
Bean
对象。 - 初始化资源查找器。
- 预留用于子类的扩展点,留待子类自行实现。
- 注册应用中的事件监听器。
- 实例化并初始化剩余的单例
Bean
对象。 - 完成刷新过程,通常包括清除缓存和发布容器生命周期事件。
下面将逐一介绍每一个步骤。
准备刷新容器
protected void prepareRefresh() {
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
initPropertySources();
this.environment.validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<>();
if (this.earlyApplicationListeners == null) {
this.earlyApplicationListeners = new LinkedHashSet<>(
this.applicationListeners);
}
else {
this.earlyApplicationListeners.addAll(this.applicationListeners);
}
this.applicationEventMulticaster = new SimpleApplicationEventMulticaster(this.beanFactory);
this.applicationEventMulticaster.setErrorHandler(new ErrorHandler() {
@Override
public void handleError(Throwable throwable) {
if (throwable instanceof BeanCreationException) {
BeanCreationException bce = (BeanCreationException) throwable;
if (logger.isErrorEnabled() && bce.getBeanName() != null) {
logger.error("Error creating bean with name '" + bce.getBeanName() + "'", bce);
}
}
}
});
// 留待容器刷新监听器进行处理
this.refreshListeners.clear();
addApplicationListener(new SourceFilteringListener(this, new RefreshListener()));
// 如果用户没有配置BeanNameGenerator,则默认使用AnnotationBeanDefinitionParser
if (this.beanNameGenerator == null) {
this.beanNameGenerator = new AnnotationBeanNameGenerator();
}
// 如果没有默认的`ClassLoader`使用当前线程的`ClassLoader`
if (this.resourceLoader == null) {
this.resourceLoader = this;
}
}
在刷新容器前准备工作主要包括以下内容:
- 设置容器的启动时间、关闭状态和活跃状态。
- 初始化属性源,如从环境中获取属性配置文件。
- 校验需要的属性是否配置完整。
- 初始化早期的
ApplicationEvent
和ApplicationListener
。 - 初始化应用事件的广播器。
- 注册容器刷新监听器,并将其添加到广播器中。
- 设置默认的
BeanNameGenerator
和ClassLoader
。
准备Bean工厂
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
refreshBeanFactory();
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
准备Bean
工厂包括刷新Bean
工厂和获取Bean
工厂,具体流程如下:
- 刷新
Bean
工厂。在这一步中会销毁原有的Bean
工厂,读取新的Bean
定义并将其装配成一个可用的Bean
组件。 - 获取
Bean
工厂,该方法返回的就是我们最终的Bean
工厂实例。
设置Bean工厂
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 添加占位符,避免因Bean依赖注入出错而导致应用启动失败
beanFactory.addBeanPostProcessor(new BeanPostProcessor() {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (bean instanceof BeanFactoryAware) {
((BeanFactoryAware) bean).setBeanFactory(beanFactory);
}
return bean;
}
});
// 设置类装载器
if (!(beanFactory instanceof DefaultListableBeanFactory)) {
return;
}
DefaultListableBeanFactory dlbf = (DefaultListableBeanFactory) beanFactory;
dlbf.setAutowireCandidateResolver(new SimpleAutowireCandidateResolver(dlbf.getBeanClassLoader()));
dlbf.setDependencyComparator(getDependencyComparator());
Set<Object> seen = Collections.newSetFromMap(new ConcurrentHashMap<>(16));
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
postProcessor.postProcessBeanFactory(dlbf);
}
if (!getBeanNamesForTypeIncludingAncestors(BeanFactoryPostProcessor.class, true, false).containsAll(this.beanFactoryPostProcessorSet)) {
LinkedList<BeanFactoryPostProcessor> nonOrderedPostProcessors = new LinkedList<>();
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
if (!this.beanFactoryPostProcessorSet.contains(postProcessor) && postProcessor instanceof PriorityOrdered) {
nonOrderedPostProcessors.add(postProcessor);
}
}
OrderComparator.sort(nonOrderedPostProcessors);
this.beanFactoryPostProcessorList.addAll(nonOrderedPostProcessors);
}
for (BeanFactoryPostProcessor postProcessor : this.beanFactoryPostProcessorList) {
postProcessor.postProcessBeanFactory(dlbf);
}
annoProcessor.setBeanFactory(beanFactory);
for (Map.Entry<Class<?>, Object> entry : scopedBeans.entrySet()) {
beanFactory.registerScope(entry.getKey().getName(), entry.getValue());
}
scopedBeans.clear();
beanFactory.setTypeConverter(new StandardTypeConverter(beanFactory.getBeanClassLoader()));
beanFactory.setTempClassLoader(null);
// 注册自定义的属性编辑器
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
beanFactory.addPropertyEditorRegistrar(new EnvironmentEditorRegistrar(getEnvironment(), getConversionService()));
}
设置Bean
工厂主要包括以下内容:
- 添加占位符,避免因
Bean
依赖注入出错而导致应用启动失败。 - 设置类装载器。
- 注册
BeanFactoryPostProcessor
对象,用于在Bean
工厂的属性值初始化之前对其进行额外的处理。(在这一步中也会为BeanFactoryPostProcessor
对象找到对应的Bean
定义,并利用反射来调用postProcessBeanDefinitionRegistry()
方法,以进一步扩展我们的容器。) - 注册自定义的属性编辑器。
加载Bean定义
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 加载Bean定义
// 数组的工厂名称已经预留出来了,为什么不用?直接调用这个方法。
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
getBeanDefinitionRegistrars().forEach(registrar -> registrar.registerBeanDefinitions(this));
getBeanDefinitionReaderListeners().forEach(listener -> beanDefinitionReader.addBeanDefinitionListener(listener));
loadBeanDefinitions(beanDefinitionReader);
}
在这一步中会创建一个XmlBeanDefinitionReader
对象,并填充容器。具体流程如下:
- 创建
XmlBeanDefinitionReader
对象,并为其设置环境参数和资源装载器等一系列属性。 - 从配置文件中读取
Bean
定义,利用BeanDefinition
实例来保存这些定义。 - 将读取到的
Bean
定义向容器中填充,并进行合适的处理,如注入依赖的其他Bean
、对属性进行设置等操作。
实例化并注入非懒加载的单例Bean对象
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 执行BeanFactoryPostProcessor的回调。通常包括Bean定义修改、Bean删减等操作
List<BeanFactoryPostProcessor> regularPostProcessors =
this.beanFactoryPostProcessorList.stream().filter(beanFactoryPostProcessor -> !(beanFactoryPostProcessor instanceof PriorityOrdered)).collect(Collectors.toList());
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : this.beanFactoryPostProcessorList) {
if (postProcessor instanceof PriorityOrdered) {
priorityOrderedPostProcessors.add(postProcessor);
}
}
AnnotationAwareOrderComparator.sort(priorityOrderedPostProcessors);
regularPostProcessors.addAll(priorityOrderedPostProcessors);
for (BeanFactoryPostProcessor postProcessor : regularPostProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
// 执行BeanDefinitionRegistryPostProcessor的回调
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
for (BeanFactoryPostProcessor postProcessor : getBeanFactoryPostProcessors()) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
currentRegistryProcessors.add((BeanDefinitionRegistryPostProcessor) postProcessor);
}
}
List<BeanDefinitionRegistryPostProcessor> registryPostProcessors = new ArrayList<>();
List<String> candidateNames = new ArrayList<>(beanFactory.getBeanDefinitionCount());
candidateNames.addAll(Arrays.asList(beanFactory.getBeanDefinitionNames()));
String[] processorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String procName : processorNames) {
if (beanFactory.isTypeMatch(procName, PriorityOrdered.class)) {
registryPostProcessors.add(beanFactory.getBean(procName, BeanDefinitionRegistryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(procName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(procName, BeanDefinitionRegistryPostProcessor.class));
}
else {
registryPostProcessors.add(beanFactory.getBean(procName, BeanDefinitionRegistryPostProcessor.class));
}
}
AnnotationAwareOrderComparator.sort(registryPostProcessors);
currentRegistryProcessors.addAll(registryPostProcessors);
Set<BeanDefinitionRegistryPostProcessor> processedBeans = new HashSet<>();
for (BeanDefinitionRegistryPostProcessor postProcessor : currentRegistryProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(beanFactory);
processedBeans.add(postProcessor);
}
currentRegistryProcessors.clear();
// 实例化BeanFactoryPostProcessor类型的Bean并回调
List<BeanFactoryPostProcessor> beanFactoryPostProcessors =
new ArrayList<>(beanFactory.getBeansOfType(BeanFactoryPostProcessor.class, true, false).values());
AnnotationAwareOrderComparator.sort(beanFactoryPostProcessors);
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
postProcessor.postProcessBeanFactory(beanFactory);
}
}
实例化并注入非懒加载的单例Bean
对象主要包括以下内容:
- 执行
BeanFactoryPostProcessor
的回调。通常包括Bean
定义修改、Bean
删减等操作。 - 执行
BeanDefinitionRegistryPostProcessor
的回调。 - 实例化
BeanFactoryPostProcessor
类型的Bean
并回调。
注册Bean后置处理器
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
this.priorityOrderedPostProcessors.add(pp);
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
this.orderedPostProcessors.add(pp);
}
else {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
this.nonOrderedPostProcessors.add(pp);
}
}
List<BeanPostProcessor> orderedPostProcessorList =
new ArrayList<>(this.priorityOrderedPostProcessors);
// we must not include priorityOrderedPostProcessors here anymore
orderedPostProcessorList.addAll(this.orderedPostProcessors);
// guarantee order within merged processors, while keeping registration order for non-Ordered ones
AnnotationAwareOrderComparator.sort(orderedPostProcessorList);
for (BeanPostProcessor postProcessor : orderedPostProcessorList) {
beanFactory.addBeanPostProcessor(postProcessor);
}
for (BeanPostProcessor postProcessor : this.nonOrderedPostProcessors) {
beanFactory.addBeanPostProcessor(postProcessor);
}
}
注册Bean
后置处理器主要包括以下内容:
- 获取在容器中所有实现了
BeanPostProcessor
接口的实例Bean
。 - 按照
BeanPostProcessor
子类的Order
顺序对Bean
后置处理器进行排序。 - 注册
Bean
后置处理器。
初始化剩余非懒加载的Bean对象
```
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 parentMessageSource if no parent message source
// registered already.
hms.setParentMessageSource(getInternalParentMessageSource());
}
}
if (logger.isTraceEnabled()) {
logger.trace("Using MessageSource [" + this.messageSource + "]");
}
}
else {
// Use empty MessageSource to be able to accept getMessage calls.
DelegatingMessageSource dms = new DelegatingMessageSource();
dms.setParentMessageSource(getInternalParentMessageSource());
this.messageSource = dms;
beanFactory
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Spring IoC学习之ApplicationContext中refresh过程详解 - Python技术站