入口
常使用的入口
public static void main(String[] args) {ApplicationContext context = new ClassPathXmlApplicationContext("bean.xml");}
我们看一下 ClassPathXmlApplicationContext 的构造函数:
ClassPathXmlApplicationContext.java
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {this(new String[]{configLocation}, true, (ApplicationContext)null);}
发现我们最终调用的构造函数是:
ClassPathXmlApplicationContext.java
public ClassPathXmlApplicationContext(String[] configLocations, boolean refresh, @Nullable ApplicationContext parent) throws BeansException {super(parent);this.setConfigLocations(configLocations);if (refresh) {this.refresh();}}
通过构造函数,我们可以分析出创建 ClassPathXmlApplicationContext 容器时,构造函数做了以下事情:
- 调用父容器的构造方法
super(parent),为容器设置好Bean 资源解析器; - 调用父类
AbstractRefreshableConfigApplicationContext的setConfigLocations(configLocations)方法,设置Bean 配置信息的定位路径; - 调用
refresh()方法。
设置Bean 资源加载器
通过追踪 super(parent) ,发现 AbstractApplicationContext 最终的构造函数:
AbstractApplicationContext.java
public abstract class AbstractApplicationContextextends DefaultResourceLoaderimplements ConfigurableApplicationContext{public AbstractApplicationContext() {this.logger = LogFactory.getLog(this.getClass());this.id = ObjectUtils.identityToString(this);this.displayName = ObjectUtils.identityToString(this);this.beanFactoryPostProcessors = new ArrayList();this.active = new AtomicBoolean();this.closed = new AtomicBoolean();this.startupShutdownMonitor = new Object();this.applicationListeners = new LinkedHashSet();// 获取一个spring source 的资源解析器this.resourcePatternResolver = this.getResourcePatternResolver();}public AbstractApplicationContext(@Nullable ApplicationContext parent) {this();this.setParent(parent);}// 获取一个spring source 的资源解析器用于读取Spring Bean 信息protected ResourcePatternResolver getResourcePatternResolver() {return new PathMatchingResourcePatternResolver(this);}}
调用 PathMatchingResourcePatternResolver 的构造函数来创建Spring 资源加载器:
PathMatchingResourcePatternResolver.java
public PathMatchingResourcePatternResolver(ResourceLoader resourceLoader) {Assert.notNull(resourceLoader, "ResourceLoader must not be null");// 设置Spring 资源加载器this.resourceLoader = resourceLoader;}
这里需要注意的是: AbstractApplicationContext 继承 DefaultResourceLoader ,因此也是一个资源加载器,所以能够作为参数。
Bean 配置信息的定位
在设置Bean 资源解析器之后,接下来 ClassPathXmlApplicationContext 通过调用父类 AbstractRefreshableConfigApplicationContext 的 setConfigLocations(configLocations) 方法,设置Bean 配置信息的定位路径.。该方法的源码如下:
AbstractRefreshableConfigApplicationContext.java
// 处理多个资源文件路径为一个字符串的情况public void setConfigLocation(String location) {// 按照",; \t\n",将多个资源文件路径进行分割,解析为数组形式this.setConfigLocations(StringUtils.tokenizeToStringArray(location, ",; \t\n"));}// 解析Bean 定义资源文件的路径,处理多个文件字符串数组public void setConfigLocations(@Nullable String... locations) {if (locations != null) {Assert.noNullElements(locations, "Config locations must not be null");this.configLocations = new String[locations.length];for(int i = 0; i < locations.length; ++i) {// resolvePath 为将字符串解析为路径的方法this.configLocations[i] = this.resolvePath(locations[i]).trim();}} else {this.configLocations = null;}}
从以上两个方法我们可以看出:我们既可以使用一个字符串来配置多个Spring Bean 资源文件信息,也可以用字符串数组进行配置。多个资源文件路径之间是可以使用“,;\t\n”进行分割。
