认识了ApplicationContext,自然就需要理解ApplicationContext如何实现的。本文主要分析通过ClassPathXmlApplicationContext(ApplicationContext后代的具体实现类之一)如何生成ApplicationContext(见下图)。
ClassPath
Spring中,ClassPath路径有如下三种:
1、项目的src/main/java路径
2、项目的src/main/resouces路径
3、第三方jar包的根路径
编译打包后,1、2位于WEB-INF/classes目录下,3位于WEB-INF/lib目录下的第三方包里。
类作用
基本作用是基于classpath查找xml定义文件,然后创建独立的应用容器。
1、自动在classpath中查找元数据配置文件。
2、文件路径可以通过getConfigLocations重新定义,支持普通文件名(如:“/myfiles/context.xml”)和Ant模式匹配文件名(如:“/myfiles/*-context.xml”)
3、注意:如果有多个配置文件且存在相同的bean定义,后面的 bean 定义将覆盖前面加载文件中定义的bean。主要目的是满足特殊场景,如通过额外的 XML 文件故意覆盖某些 bean 定义的情况。
类继承
图中继承类说明如下:
AbstractXmlApplicationContext
该类作用就是解析xml格式配置的Bean元数据,从而加载Bean定义。子类除了ClassPathXmlApplicationContext,还有FileSystemXmlApplicationContext。
具体解析见:https://blog.youkuaiyun.com/davidwkx/article/details/130702324
AbstractRefreshableConfigApplicationContext
该类作用就是提供对配置文件位置的解析。详见:https://blog.youkuaiyun.com/davidwkx/article/details/130768774
AbstractRefreshableApplicationContext
该类作用就是刷新BeanFactory–关掉原来BeanFactory,基于容器重新构建BeanFactory。可以理解为在一个运行的容器中,可重新加载Bean,从而方便实现热更新。详见:https://blog.youkuaiyun.com/davidwkx/article/details/130700416
AbstractApplicationContext
构建ApplicationContext的绝大部分工作在该类完成。详见:https://blog.youkuaiyun.com/davidwkx/article/details/130671056
DefaultResourceLoader
主要实现ResourceLoader接口。详见:https://blog.youkuaiyun.com/davidwkx/article/details/130768842
从继承图看, 类继承深达6层,显得很复杂。至于为什么这么设计,我们需要逐一阅读这些类代码,然后思考总结这样设计的意义。
类实现
该类的方法基本都是各种参数的构建方法,实际执行是跳转到如下核心构建方法:
public ClassPathXmlApplicationContext(
String[] configLocations, boolean refresh, @Nullable ApplicationContext parent)
throws BeansException {
//设置parent,实际处理在AbstractApplicationContext
super(parent);
//根据传入的配置文件名初始化到ConfigLocations,调用AbstractRefreshableConfigApplicationContext.setConfigLocations
setConfigLocations(configLocations);
//调用AbstractApplicationContext.refresh()生成容器
if (refresh) {
refresh();
}
}
代码逻辑就是把传入的配置参数文件名放到configLocations,然后调用祖先类的refresh()初始化容器。对比了下FileSystemXmlApplicationContext,逻辑也一样。
注意:上述代码的中的“//+中文"注释行是笔者在跟踪阅读代码时加上自我理解说明(系列后续文章同样处理)。
ClassPathXmlApplicationContext初始化序列图
下图是ClassPathXmlApplicationContext初始化序列图,主要体现继承类中方法的实现位置(忽略其它调用),可体会继承设计意图: