Spring源码解读之执行流程
1、加载resources下面的context.xml配置文件
public static void main(String[] args){
ClassPathXmlApplicationContext application = new ClassPathXmlApplicationContext("classpath:context.xml");
Test test = application.getBean(Test.class);
}
2、context.xml的配置内容为:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id = "test" class="com.reus.Test" />
</beans>
3、执行流程为:
先调用构造方法public ClassPathXmlApplicationContext(String configLocation),在调用构造方法public ClassPathXmlApplicationContext(String... configLocations),最后执行构造方法public ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent),其中refresh为true,parent为null,即刷新上下文同时设置父上下文为null。设置父上下文时会一直调用构造函数直至AbstractApplicationContext。调用流程为
1、ClassPathXmlApplicationContext#ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
2、AbstractXmlApplicationContext#AbstractXmlApplicationContext(ApplicationContext parent)
3、AbstractRefreshableConfigApplicationContext#AbstractRefreshableConfigApplicationContext(ApplicationContext parent)
4、AbstractRefreshableApplicationContext#AbstractRefreshableApplicationContext(ApplicationContext parent)
5、AbstractApplicationContext#AbstractApplicationContext(ApplicationContext parent)
设置AbstractApplicationContext#AbstractApplicationContext()中的resourcePatternResolver
创建资源解析器:AbstractApplicationContext#getResourcePatternResolver()
设置上下文的父上下文AbstractApplicationContext#setParent(@Nullable ApplicationContext parent)
该方法的作用是设置上下文的父上下文,如果父上下文不为空则合并父上下文中的环境变量到本上下文。至此ClassPathXmlApplicationContext父类构造方法的执行完毕。
再回到ClassPathXmlApplicationContext#ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)方法中。super(parent)执行之后setConfigLocations(configLocations),该方法为AbstractRefreshableConfigApplicationContext类中的方法,
AbstractRefreshableConfigApplicationContext#setConfigLocations(@Nullable String... locations)
此方法的作用是设置AbstractRefreshableConfigApplicationContext中属性configLocations的值,即所有配置文件的路径,同时如果路径中包含占位符(${}),则会被替换掉。
ClassPathXmlApplicationContext#ClassPathXmlApplicationContext( String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)构造方法中执行完setConfigLocations(configLocations)语句之后,根据refresh决定是否执行AbstractApplicationContext#refresh(),refresh默认true,因此再次回到AbstractApplicationContext#refresh()中
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//refresh之前执行的操作
(1)prepareRefresh();
// 子类refresh 内部beanfactory.
(2)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
// 创建beanfactory
(3)prepareBeanFactory(beanFactory);
try {
// 创建beanfactory的后置操作
(4)postProcessBeanFactory(beanFactory);
// 调用factory处理器将工厂作为bean注册到上下文中
(5)invokeBeanFactoryPostProcessors(beanFactory);
// 注册bean后置处理器用来代理bean的创建
(6)registerBeanPostProcessors(beanFactory);
// 初始化国际化
(7)initMessageSource();
// 初始化这个上下文的事件发送器
(8)initApplicationEventMulticaster();
// 初始化其他指定的bean
(9)onRefresh();
// 检查所有的监听器beans同时注册他们到这个上下文中
(10)registerListeners();
// 初始化所有非延迟加载的单例类
(11)finishBeanFactoryInitialization(beanFactory);
// 最后一步发送匹配的事件
(12)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();
}
}
}
(1)、执行方法AbstractApplicationContext#prepareRefresh
protected void prepareRefresh() {
// 设置本上下文启动事件
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());
}
}
// 初始化本上下文配置文件环境变量
initPropertySources();
// 校验所有的配置文件已经完成路径解析
// 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<>();
}
此方法的主要目的是初始化一些必须的参数,如环境变量(environment),设置上下文启动时间、将上下文的active设置为true、cloesed设置为false、earlyApplicationListeners、earlyApplicationEvents。
(2)、AbstractApplicationContext#obtainFreshBeanFactory
protected ConfigurableListableBeanFactory obtainFreshBeanFactory() {
//抽象方法,由子类继承用于销毁本上下文中所有的bean工厂并重新创建工厂
refreshBeanFactory();
return getBeanFactory();
}
AbstractApplicationContext#obtainFreshBeanFactory中refreshBeanFactory的实现类为:
AbstractRefreshableApplicationContext#refreshBeanFactory
//此方法为final不允许子类继承
protected final void refreshBeanFactory() throws BeansException {
if (hasBeanFactory()) {
//销毁所有的bean
destroyBeans();
//关闭bean工厂
closeBeanFactory();
}
try {
//创建bean工厂
DefaultListableBeanFactory beanFactory = createBeanFactory();
//设置bean工厂的序列化id
beanFactory.setSerializationId(getId());
//定制bean工厂
customizeBeanFactory(beanFactory);
//加载所有的bean定义到工厂中
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
在该方法中最重要的应该就是loadBeanDefinitions,这是一个抽象方法,其主要目的就是解析配置文件中定义的bean,就是的实现为AbstractXmlApplicationContext#loadBeanDefinitions
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// 为bean工厂创建一个XmlBeanDefinitionReader
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// 根据上下文配置XmlBeanDefinitionReader
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// 加载配置文件的逻辑,允许子类进行重写覆盖
initBeanDefinitionReader(beanDefinitionReader);
loadBeanDefinitions(beanDefinitionReader);
}
//配置是否需要校验xml的格式
protected void initBeanDefinitionReader(XmlBeanDefinitionReader reader) {
reader.setValidating(this.validating);
}
//遍历所有的配置文件并解析所有的配置
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
reader.loadBeanDefinitions(configLocations);
}
}
(3)、创建完成bean工厂,同时加载完成所有的配置文件中的配置,此时配置bean工厂一些更详细的细节
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// 配置bean工厂的类加载器
beanFactory.setBeanClassLoader(getClassLoader());
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//忽略掉一些接口依赖
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 interface not registered as resolvable type in a plain factory.
// MessageSource registered (and found for autowiring) as a bean.
beanFactory.registerResolvableDependency(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));
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (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()));
}
// 注册一些默认的bean
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
(5)、调用bean工厂的后置处理器 //TODO
(6)、注册bean的后置处理器用于拦截bean的创建
(7)、国际化
(8)、设置ApplicationEventMulticaster
(9)、空方法
(10)、将所有的ApplicationListener添加到ApplicationEventMulticaster
(11)、实例化所有的非延迟加载的bean
(12)、完成上下文的创建发送ContextRefreshedEvent事件