应用上下文创建流程概览
源码剖析
- 创建Spring应用程序上下文
ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
- 进入ClassPathXmlApplicationContext构造函数
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
super(parent);
setConfigLocations(configLocations);
if (refresh) {
refresh();
}
}
(1)调用父类构造方法,创建Reslover,解析配置文件
(2)设置配置文件路径到当前应用程序中
(3)开始调用refresh(),进行容器的创建
- 进入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);
// Invoke factory processors registered as beans in the context.
invokeBeanFactoryPostProcessors(beanFactory);
// Register bean processors that intercept bean creation.
registerBeanPostProcessors(beanFactory);
// 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();
}
(1) prepareRefresh:做前期准备
- 设置容器的启动时间
- 设置活跃状态为true
- 设置关闭状态为false
- 获取Environment对象,并加载当前系统的属性值到Environment对象中
- 准备监听器和事件对象的集合
(2) obtainFreshBeanFactory
创建容器并完成配置文件加载
(3) prepareBeanFactory
通过一系列的add, set, ignore, register开头的方法,给容器对象进行赋值
(4) postProcessBeanFactory: 默认没有实现,留给子类去实现
(5) invokeBeanFactoryPostProcessors
可进行自由扩展,修改BeanFactory的相关信息。比如:ConfigurationClassPostProcessor, PropertySourcePlaceHolderConfigurer
(6) registerBeanPostProcessors
注册BeanPostProcessor,完成spring自带的或者用户自定义的BeanPostProcessor的解析
(7) initMessageSource
进行国际化相关的操作
(8) initApplicationEventMulticaster
初始化事件广播器
(9) onRefresh: 默认没有实现,由子类去定义
(10) registerListener: 注册监听器,接收广播的事件
(11) finishBeanFactoryInitialization:完成对象的实例化操作
从此方法开始进行对象的创建,包含实例化,初始化,循环依赖,AOP等核心逻辑的处理过程。
(12) finishRefresh
完成整个容器的启动,所有对象都准备完成。清除上下午缓存,初始化生命周期处理器,并发送刷新完成事件。
Bean的创建
前面说到了在finishBeanFactoryInitialization()方法中会进行对象的创建。下面来进一步看下Bean是如何创建的:
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// Initialize conversion service for this context.
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
// Register a default embedded value resolver if no bean post-processor
// (such as a PropertyPlaceholderConfigurer bean) registered any before:
// at this point, primarily for resolution in annotation attribute values.
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// Initialize LoadTimeWeaverAware beans early to allow for registering their transformers early.
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
// Allow for caching all bean definition metadata, not expecting further changes.
beanFactory.freezeConfiguration();
// Instantiate all remaining (non-lazy-init) singletons.
beanFactory.preInstantiateSingletons();
}
(1)setConversionService:设置类型转换服务
(2)addEmbeddedValueResolver:设置内置的值处理器
(3)freezeConfiguration:冻结BeanDefinition
(4)preInstantiateSingletons(关键步骤):
开始对象的实例化:
// Iterate over a copy to allow for init methods which in turn register new bean definitions.
// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
// Trigger initialization of all non-lazy singleton beans...
for (String beanName : beanNames) {
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
if (isFactoryBean(beanName)) {
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
if (isEagerInit) {
getBean(beanName);
}
}
}
else {
getBean(beanName);
}
}
}
从容器中获取所有的BeanDefinitionNames集合,从每个集合中获取每一个元素,来进行对象的创建。
根据BeanName来获取完整的BeanDefinition对象。再通过getBean()来获取Bean对象,里面调用的doGetBean()。
这其中涉及到整个Bean的创建,属性填充,实例化等一些列操作,大致流程如下:
这其中涉及到spring对Bean对象的三级缓存,后面会再来详细说下这个问题。