ApplicationContext初始化源码

ApplicationContext和BeanFactory都是用于加载Bean的,该接口用于扩展BeanFactory功能,比BeanFactory更强大。

在这里插入图片描述

@Override
	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的解析,读取xml文件
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// Prepare the bean factory for use in this context.
			//支持@Qualifier和@Autowried注解,属性填充
			prepareBeanFactory(beanFactory);

			try {
				// Allows post-processing of the bean factory in context subclasses.
				postProcessBeanFactory(beanFactory);

				// Invoke factory processors registered as beans in the context.
				// 激活各种beanFactory处理器
				invokeBeanFactoryPostProcessors(beanFactory);

				// Register bean processors that intercept bean creation.
				//注册各种bean处理器,只是注册,真正调用在getBean时
				registerBeanPostProcessors(beanFactory);

				// Initialize message source for this context.
				//初始化Message源,即对不同语言的消息体进行国际化处理
				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.
				// 查找listener bean注册到消息广播器中。
				registerListeners();

				// Instantiate all remaining (non-lazy-init) singletons.
				// 初始化非惰性的 单例bean
				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();
			}
		}
	}

prepareRefresh方法

作用是准备系统环境变量
在这里插入图片描述

obtainFreshBeanFactory方法
1.refreshBeanFactory
在这里插入图片描述
2.getBeanFactory
在这里插入图片描述
prepareBeanFactory方法
对ApplicationContext进行功能扩展
在这里插入图片描述


这个resolver解析器是在什么时候调用的呢?上篇文章提到过,回顾下。
在调用getBean方法时,先通过beanDefinition和beanName创建实例对象(通过参数决定哪个构造函数,并查看是否有覆盖方法,来决定使用反射构建还是CGlib构建),然后暴露ObjectFactory(用于单例),并调用populateBean方法注入属性(根据type或name来注入),然后调用哪些初始化bean的方法(例如beanPostProcessor、init方法等)。

解答:这个解析器的调用当然是在populateBean方法中,可以记得有这样一个方法applyPropertyValues方法(注入属性的)。通过valueReslver来进行属性值的的解析。
在这里插入图片描述
除了设置当前classloader、语言解析器,还注册了beanPostProcessor。然后还忽略了一些依赖,用于在依赖注入时忽略这些bean。


在这里插入图片描述


再来回顾一下beanPostProcessor的流程吧~
首先先执行beanPostProcessor的before方法、然后是afterProperties方法、接着init指定方法、最后是bpp的after方法。忘记的看我之前的文章。
看看这个ApplicationContextAware吧
在这里插入图片描述


在这里插入图片描述
我当时看到代码中有

@Autowried 
ApplicationContext applicationcontext;

这也就解释了为什么能注入进去了。


BeanFactoryPostProcessor和bpp类似,可以在容器实际实例化任何其他bean之前读取配置元数据,并可能修改它。beanFactoryPostProcessor作用范围是容器级别的,它仅仅对容器bean进行后置处理。只和你所使用的容器有关。bfpp不会对定义在另一个容器中的bean进行后置处理。典型应用是PropertyPlaceholderConfigurer。
例如这样的配置:

<!-- 配置dbcp数据源 -->
<bean id="dataSourceDefault" class="org.apache.commons.dbcp.BasicDataSource">
	<property name="driverClassName" value="${jdbc.driverClassName}" />
	<property name="url" value="${jdbc.url}" />
	<property name="username" value="${jdbc.username}" />
	<property name="password" value="${jdbc.password}" />
</bean>

它会将这些value从配置文件中替换成正确的内容。当然我们也可以自己定义一些bfpp来实现我们想要的功能。比如说,去除属性值是敏感词的。


invokeBeanFactoryPostProcessors方法
在这里插入图片描述
有三种记录后处理器的List
1.registryPostProcessors:通过硬编码方式注册的BeanDefinitionRegistryPostProcessor
2.regularPostProcessor:记录通过硬编码方式注册的BeanFactoryPostProcessor类型的处理器。
3.registryPostProcessorBeans:记录通过配置方式注册的BeanDefinitionRegistryPostProcessor类型的处理器。

在这里插入图片描述
紧接着会对所有记录的后处理器统一调用postProcessBeanDefinitionRegistry、postProcessBeanFactory方法。
在这里插入图片描述
在这里插入图片描述
registerBeanPostProcessors方法
这里看名字就知道是注册bpp的地方。bpp的处理中并没有加入硬编码方式,是因为bpp并不需要立即被调用。可以在开发时想想,我这个定制化是在什么时候才需要执行的。
在这里插入图片描述
对于beanFactory的注册,不是直接注册的。在Spring中支持对bpp的排序,比如根据PriorityOrdered排序,根据Ordered排序或无序方式。这样激活顺序就需要考虑到。
在这里插入图片描述
initMessageSource方法
它是用来初始化消息资源的方法。用于国际化。(我是感觉只要做了国际化,那么这个系统就废了)

initApplicationEventMulticaster方法
用于注册事件广播器
在这里插入图片描述
看一下SimpleApplicationEventMulticaster是如何将事件交给事件监听器
在这里插入图片描述
registerListeners方法
该方法用于注册监听器
在这里插入图片描述

finishBeanFactoryInitialization方法
完成beanFactory初始化工作,包括ConversionService设置、配置冻结以及非延迟加载bean的初始化工作。
1.ConversionService的使用
Spring数据转换(一)–ConversionService

2.配置冻结意味着bean定义将不被修改或者进行任何一步处理。
在这里插入图片描述
3.preInstantiateSingletons实例化单例bean
在这里插入图片描述
finishRefresh方法
在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值