源代码分析,是一件既痛苦又快乐的事情,看别人写的代码是通过的,但当你能够看明白的时候,相信快乐也会随之而来,为了减少痛苦,更快的带来快乐,在这里希望通过这篇文章对觉得困难的朋友有一个帮助。 ) T1 l6 F: r. y, ?2 ]. ^# w. ?( m' ?4 k* P
本文以spring框架的XmlBeanFactory为入手点进行分析,希望能够以尽量简洁明了的方式给予有需要的朋友一定的帮助。 ( i7 S! }0 `3 S$ |: J, w, ?/ `- t+ K& C3 K$ ~
首先来打开该类的代码,我们将看到如下代码: a* ~9 I5 ]+ F' H* h
以下内容为程序代码: 6 y) Z. m# J0 J7 c) U% \9 o$ t3 i% {2 i9 Y. I. Z, Q! z# ^
public class XmlBeanFactory extends DefaultListableBeanFactory {* I7 |1 @- K% B) \9 U
& P4 Q$ }. }* e I4 f3 a4 o8 Z private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);2 D# E4 i/ B, v! Z: A
E3 W. M9 i% r; P5 x) `
public XmlBeanFactory(Resource resource) throws BeansException {, X H5 f8 o6 T$ ~5 m
this(resource, null);1 h" [ X( _5 Z' R0 c
} ( W; N) a, l3 q) F$ Z ( Y- j8 F4 @ H$ { public XmlBeanFactory(Resource resource, BeanFactory parentBeanFactory) throws BeansException { 1 r/ t% T T/ b0 N super(parentBeanFactory); / d/ F6 D* I7 N+ s6 ^ this.reader.loadBeanDefinitions(resource); 2 ]0 P8 p x% X$ [& [ }: u% v1 M7 j6 r5 I
5 I( S0 q% x1 o) z, T, t& [) P
}" R% V I: J- c$ A. ^* [; A
8 U! w2 Y0 R6 E& k: b
. w A% D7 x) J' E' R
这个类的代码很简单,一个成员对象加两个构造函数,从这里我们可以看出,最重要的地方在于最后一个构造函数: 5 `6 h' [4 o4 c" |, _% O- @$ f 3 `/ G! Q8 A' N! L+ h; H9 Z. y" L以下内容为程序代码:$ g6 {. `9 `. V7 `% T5 C
3 V% P3 h6 j! ?9 j super(parentBeanFactory); . Y% g. P+ n6 H0 }% {' H* D/ D! \ this.reader.loadBeanDefinitions(resource);1 f% y( m% o" t/ @) a. f
+ I) E7 G$ G, |4 k: x
3 F1 V8 T( u3 I ^7 [0 J. K0 ?
第一句就是将父亲工厂交给父类的构造函数,实际上最后也就是把父工厂保存到类的parentBeanFactory成员对象中,这个对象是在AbstractBeanFactory抽象类中定义的,而这个父工厂也会一直传递到该抽象类进行保存。第二句就是整个类中最重要的地方了,顾名思义,它的目的是通过XmlBeanDefinitionReader这个XML的Reader从资源resource中(也就是你的配置文件)读取bean的定义。接下来我们打开XmlBeanDefinitionReader的loadBeanDefinitions方法,我们可看到在这个方法里代码就一行,调用了一个同名不同参的方法,而参数是EncodedResource的一个实例,这个类实际上是Resource的一个包装类,用来保存资源的Encode的,那接下来我们再看被调用的loadBeanDefinitions方法,这个方法里最主要的部分就是: J3 w) @( T- k8 j9 Y . v. I- L5 A0 b, `; h: h7 \, v以下内容为程序代码:* {, ?0 e. q6 S$ d5 m, c
5 I" B* A% B2 [. I }2 b3 B InputSource inputSource = new InputSource(inputStream); 1 w* ]1 Z' n' J" A if (encodedResource.getEncoding() != null) { 1 I ]1 U# Y2 m- [4 A, i1 e* N: K& m inputSource.setEncoding(encodedResource.getEncoding());( _3 B& O! C# a: w6 k3 r
} * N' K2 ~, t, p. o0 L return doLoadBeanDefinitions(inputSource, encodedResource.getResource()); 4 M( d! y$ R% l3 ?/ g9 N0 n; E* d& o3 ]/ N% f4 x: Y