上一篇我们说到了spring1.0的基本配置使用,特别需要注意的是spring1.0的bean.xml文件是没有名称空间的,只有文档的定义信息。
那么本篇,我们来看一下spring1.0版本的容器是如何初始化的,bean是怎么创建出来的,篇幅较长,请大家耐心阅读,如果有什么错误的地方,欢迎大家指正。
无论是spring1.0还是spring5.0,其核心思想都离不开容器的初始化,bean的注入,后置处理器的使用等等功能,那么spring后面的版本提供了很多复杂的功能,这对我们阅读源码有一定的影响,而spring1.0所提供的功能比较简单,阅读起来也比较方便。
好了,话不多说,我们先来看看上一篇里面,创建容器的的方法
public class MySpringTest01 {
private ClassPathXmlApplicationContext applicationContext;
@Before
public void getContext(){
//容器初始化
applicationContext = new ClassPathXmlApplicationContext("bean01.xml");
}
@Test
public void test1(){
Person person1 = (Person) applicationContext.getBean("person");
System.out.println("person1:" + person1);
Person person2 = (Person) applicationContext.getBean("person");
System.out.println("person2:" + person2);
System.out.println(person1 == person2);
}
}
下面我们来看一下ClassPathXmlApplicationContext这个类里面干了什么事情
public class ClassPathXmlApplicationContext extends AbstractXmlApplicationContext {
private String[] configLocations;
//这个就是我们上一步创建对象时调用的方法,传入了一个bean.xml地址的参数
public ClassPathXmlApplicationContext(String configLocation) throws BeansException {
//将bean.xml文件地址保存在configLocations里面
this.configLocations = new String[]{configLocation};
//调用刷新容器方法
this.refresh();
}
public ClassPathXmlApplicationContext(String[] configLocations) throws BeansException {
this.configLocations = configLocations;
this.refresh();
}
public ClassPathXmlApplicationContext(String[] configLocations, ApplicationContext parent) throws BeansException {
super(parent);
this.configLocations = configLocations;
this.refresh();
}
protected String[] getConfigLocations() {
return this.configLocations;
}
}
我们先看下ClassPathXmlApplicationContext这个类的继承关系
可以看到ClassPathXmlApplicationContext是继承自AbstractXmlApplicationContext的,而AbstractXmlApplicationContext又继承自AbstractApplicationContext
我们看下每个父类中的方法
从图中我们可以看到ClassPathXmlApplicationContext调用的refresh()方法,其实就是调用父类AbstractApplicationContext的refresh()方法,那我们现在主要就是分析这个方法的执行过程
public void refresh() throws BeansException {
//获取当前时间
this.startupTime = System.currentTimeMillis();
//创建beanFactory容器,同时解析bean.xml文件,并将bean的定义信息保存起来
this.refreshBeanFactory();
//获取当前容器
ConfigurableListableBeanFactory