spring源码我也不是很了解,原来几次下定决心去看但一直不知道入口在哪里,但这是进阶必须要迈过的一个坎,下面我按照自己现在的思路来对spring源码进行阅读,首先从spring如何管理bean开始
首先咱们看看spring管理bean的一个小demo
public class Test {
public static void main(String[] args) {
/**
* 首先看看spring怎么对bean进行初始化,一般来说有两种办法
* 1、使用beanFactory
* 2、使用applicationContext
* 下面我分别使用两种方式进行初始化,并看看两种方式的源码有何不同
*/
//使用beanFactory
Resource resource = new ClassPathResource("springresourceConfiguration.xml");
BeanFactory beanFactory = new XmlBeanFactory(resource);
Engine engine = (Engine)beanFactory.getBean("engine");
System.out.println(engine.toString());
Car car = (Car)beanFactory.getBean("car");
car.introduce();
//使用applicationContext
ApplicationContext ctx = new ClassPathXmlApplicationContext("springresourceConfiguration.xml");
Engine e = (Engine)ctx.getBean("engine");
System.out.println(e.toString());
Car c = (Car)ctx.getBean("car");
c.introduce();
}
}
springresourceConfiguration.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"
xmlns:p="http://www.springframework.org/schema/p"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
">
<bean id="car" class="com.kevindai.IOCresourcecode.Car">
<property name="engine" ref="engine" />
</bean>
<bean id="engine" class="com.kevindai.IOCresourcecode.Engine"></bean>
</beans>
Car和Engine的代码很简单我就不帖出来了
这样一个spring管理bean的demo就出来了,首先咱们思考一下上面一个demo的经历了哪些流程,我个人认为至少有一下几步
1、读取配置文件
2、解析配置文件
3、把解析出来的bean交给spring管理
4、按照一定的对应关系把bean组装起来(car中需要engine)
5、初始化bean
这个是我个人的观点,不一定准确,但咱们可以顺着这个思路看下去,然后跟源码对比看看思路是否正确,OK,源码阅读开始
首先看第一行Resource resource = new ClassPathResource(“springresourceConfiguration.xml”);这个应该跟咱们思路一致是用于读取配置文件的,看看spring源码中如何处理
上图中能看到,读取配置文件时最主要做了两件事:
1、获取配置文件路径
2、初始化classLoader
———————————————————————————————————————————————————————
这里可能有些同学就要问了,获取配置文件路径好理解,那classLoader又是什么呢?这里简单解释一下:
classLoader是类装载器,在java.lang包中,它是一个重要的JRE组件,负责在运行时查找和装载Class文件.也就是说所有的类都能通过全限定类名从classLoader中获取类信息.———————————————————————————————————————————————————————
然后看第二行BeanFactory beanFactory = new XmlBeanFactory(resource);
这里有两步操作,咱们分别分析,首先看第一步对beanFacotry的处理,顺着源码追寻,最终会在AbstractBeanFactory中看到,这里是为了对parentBeanFactory做初始化用于做bean继承关系的支持,但在咱们这个简单的demo中parentBeanFactory最终是Null,所以咱们先不关注
然后看第二步,经过一番追寻,最终定位到DefaultBeanDefinitionDocumentReader的doRegisterBeanDefinitions方法,源码如下
这个方法很关键,这里会循环递归的对xml文件节点进行解析,目前看来咱们第二步的推测也算合理,
下面看看主要的解析过程parseBeanDefinitions(root, this.delegate);