Spring起动<二>——XmlWebApplicationContext
在上一篇《Spring启动<一>》中,我们已经看到了Spring的启动过程的核心就是XmlWebApplicationContext的实例化及对其属性的设置。这一篇我们看看XmlWebApplicationContext实例化的过程,我们有如下的代码:
ConfigurableWebApplicationContext wac = (ConfigurableWebApplicationContext) BeanUtils.instantiateClass(XmlWebApplicationContext.class);
这一步简单的对XmlWebApplicationContext进行实例化。XmlWebApplicationContext没有提供构造器,因此使用默认的构造器。通过源代码知道,XmlWebApplicationContext涉及到以下几个类:
- A : org.springframework.web.context.support.AbstractRefreshableWebApplicationContext
- B : org.springframework.context.support.AbstractRefreshableConfigApplicationContext
- C : org.springframework.context.support.AbstractRefreshableApplicationContext
- D : org.springframework.context.support.AbstractApplicationContext
- E : org.springframework.core.io.DefaultResourceLoader
XmlWebApplicationContext依次继承于它们,并在继承过程中实现若干接口,示意如下:XmlWebApplicationContext extends A, A extends B, B extends C, C extends D, D extends E。因此在XmlWebApplicationContext通过默认构造器实例化的时候我们要依次查看E、D、C、B、A的构造器都做了什么。XmlWebApplicationContext以及A、B、C、D、E的构造器代码如下:
public XmlWebApplicationContext(){ super(); } public A() { super(); setDisplayName("Root WebApplicationContext"); } public B() { super(); } public C() { super(); } public D() { this(null); } public D(ApplicationContext parent) { super(); this.parent = parent; this.resourcePatternResolver = getResourcePatternResolver(); } public E() { this.classLoader = ClassUtils.getDefaultClassLoader(); }
根据构造器的执行顺序,先看构造器E,通过查看源代码知道这一步的实质等同于如下语句:
private ClassLoader classLoader = Thread.currentThread().getContextClassLoader();
再看D的构造器,有两个语句,第一步只是简单的赋值this.parent = null, 第二步执行了一个方法返回一个值,查看该方法的注释我们得知,该方法返回的是一个ResourcePatternResolver实现类,该类用来处理将路径指向的资源实例化,默认的类是org.springframework.core.io.support.PathMatchingResourcePatternResolver,该类支持ant样式的路径。
构造器C是个默认构造器,没有执行任何操作。
构造器B是个默认构造器,没有执行任何操作。
构造器A中调用了一个方法,public void setDisplayName(String displayName)方法在类D中定义,只是进行简单的赋值操作。
到这里XmlWebApplicationContext就实例化成功了。