return registerBeanDefinitions(doc, resource); 2 Y' c1 a2 m9 n& g
复制代码
3 N/ R: l7 w* V1 y- Z0 F, M, J8 f2 U" e
这个方法的目的一目了然,就是为了将资源解释成为Document对象,然后调用registerBeanDefinitions方法,这里不做详细解释,不了解的话请去看看关于JAXP的介绍。接下来我们打开registerBeanDefinitions方法:! ]2 Y: _% ?+ l q5 m+ w
以下内容为程序代码: - d" v2 ~+ o) ]" V5 B9 ?& J& m. s6 L5 g+ [! P i8 v* w6 D
public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException {9 c0 o* ` \" P2 Z' h
XmlBeanDefinitionParser parser =; w6 z+ o7 h; |0 e3 ?
(XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass); & L9 V; P0 r/ S2 V; D; z' f, Q return parser.registerBeanDefinitions(this, doc, resource); 8 T, @* \( |" C- _ b% m2 ` }, {9 R! D" I6 A$ q: x0 v5 \+ i
D- V# o' f/ U; F/ n- z) h$ Y
1 K1 M5 b3 T6 q# U$ A
这里创建了一个XmlBeanDefinitionParser接口的实现,这个接口的具体类是DefaultXmlBeanDefinitionParser,这个接口很简单,只有registerBeanDefinitions一个方法,这个方法的作用也很明了,就是用来注册Bean的定义的,所以说类和方法的名字一定要起得有意义,这样可以让人一看就大概了解其作用,减少了很多阅读代码的痛苦。废话不多说,我们打开DefaultXmlBeanDefinitionParser的registerBeanDefinitions方法,这个类就是解释XML配置文件的核心类了,打开registerBeanDefinitions方法后我们看到如下代码:6 `: t4 ^' J4 Y8 @; m
以下内容为程序代码: 7 h- E3 J" i0 t: e3 o4 K! s! G$ s: n8 a y3 n) l! I
public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource)1 H2 q/ o) i0 }" l. p( V/ j) r
throws BeanDefinitionStoreException {1 I' p6 }, ]8 |. i0 F% {/ @
! m$ @ g \% w6 W7 T- O. ?4 ^ this.beanDefinitionReader = reader;3 Y9 l8 K4 N, _7 i& c3 D
this.resource = resource;8 Z3 k" ~) J' v: O- a
4 T7 E# w4 N; j/ M2 J* d
logger.debug("Loading bean definitions"); ! L" _5 j, {" Z* `! a/ t1 `8 { Element root = doc.getDocumentElement();0 C9 L: N1 C- |. c! X& }5 u
//初始化根元素8 M7 g3 {6 y1 }( _0 b9 n
initDefaults(root); 9 r# ?4 O7 e4 I$ L6 F& [ if (logger.isDebugEnabled()) {3 ^* T( N; `4 a4 {* d( |" Z
logger.debug("Default lazy init '" + getDefaultLazyInit() + "'");8 [# A8 a/ e+ g3 E
logger.debug("Default autowire '" + getDefaultAutowire() + "'");& Q9 e+ p) d) P" b+ b& S
logger.debug("Default dependency check '" + getDefaultDependencyCheck() + "'"); o, R* l0 q5 R
} $ j; ~; u" K; L4 k # c0 a( H" X1 N preProcessXml(root);//一个空方法用于扩展3 F/ @( x5 }* l! \% Z# c. P
int beanDefinitionCount = parseBeanDefinitions(root);//解释配置的主要方法 $ k" D% @1 D E* o9 V if (logger.isDebugEnabled()) { $ A( M- [( Y7 b9 x, @ logger.debug("Found " + beanDefinitionCount + " <bean> elements in " + resource);" e2 Y! K. ]) S# I/ n
} 0 |$ [* R6 p2 b7 a$ Y) h postProcessXml(root); //一个空方法用于扩展 ) \% W' W* L( N8 D8 Z3 Q " r* I* b& Y3 Y7 Q- k2 T return beanDefinitionCount; 5 K5 Z* x$ C: @" ?' E! @7 R }- j- O! M- [4 t7 k+ p
8 H U* ], H- a$ d* n v5 t( I' I. |! N. n" l, p
在这个方法当中,主要用于解释定义的有两个方法,一个是initDefaults,一个是parseBeanDefinitions,第一个方法是用来解释根元素的属性的,例如lazy-init, autowire等,而parseBeanDefinitions就是用来解释具体的bean定义了,方法代码如下:5 m6 K' X- s0 L
以下内容为程序代码:* _6 c& Q/ ^; q+ s/ V% h8 z% e+ a
4 K! F0 j( W0 V3 y0 L protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException { / ~& R2 C' [2 d K4 l) e V! @ NodeList nl = root.getChildNodes(); ) E; L5 T; h: m6 Q- Z: U int beanDefinitionCount = 0; & C- a* ], a: H* D for (int i = 0; i < nl.getLength(); i++) { 1 ~# [( ?' O9 w1 i% u Node node = nl.item(i); ' @, K" a. g4 R W if (node instanceof Element) { $ d3 } U1 r; d4 b) p Element ele = (Element) node;. |5 Y- [+ A. N1 C, D
if (IMPORT_ELEMENT.equals(node.getNodeName())) { 8 s, y4 j1 D; I) E" l/ o1 D: N importBeanDefinitionResource(ele); 9 X& e/ A7 o1 d3 r } $ `6 I) {+ h, J5 s6 J1 e else if (ALIAS_ELEMENT.equals(node.getNodeName())) {# x1 ~2 Y7 G: t- V: s" g" x
String name = ele.getAttribute(NAME_ATTRIBUTE);+ q: { v' P. s3 F: g5 D& E% }
String alias = ele.getAttribute(ALIAS_ATTRIBUTE);/ }6 |6 Q: m t2 {, r
this.beanDefinitionReader.getBeanFactory().registerAlias(name, alias); ( {8 \9 `/ b7 g, s3 E, J }6 ~- P' P& B8 p' W
else if (BEAN_ELEMENT.equals(node.getNodeName())) { * G1 R1 L h6 ]( q0 B; ]6 d/ w beanDefinitionCount++;( _; |, j! @$ h1 {6 \
BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false); 0 T, v, b# ^( o. g8 H$ e BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); , ?# Z# ^7 i5 S) v ?0 V }3 B9 R9 _! y5 W/ G# {+ D {
}; Q$ i8 q' j' u& T: e# o) g
} $ \. K( c: z4 @1 k return beanDefinitionCount; 2 H0 D& ~: V& N N* I } + H$ o. z0 C, T! J" m8 Q D) q5 C Q+ S. G* O
* W) ~, a3 V' F) S+ A
其他标签具体如何被解释这里就不多说,相信大家也能看得懂,这里主要讲一下解释bean的的处理,我们注意以下代码:2 I! `4 S1 G6 \6 ]3 g
以下内容为程序代码: $ ?+ y# \, l6 G" |+ c8 u 3 ~ l2 \5 V# M0 E else if (BEAN_ELEMENT.equals(node.getNodeName())) { 5 G. F5 N$ d. V6 t& q0 d beanDefinitionCount++; + v" a/ i" h+ G* p) k) _ BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false); 6 l$ @; T2 B3 x: W% _" e+ n BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); - i* I; a: d( x3 w2 ^5 I9 K } * u7 t- U# @! {9 _' T 4 l5 P1 n3 U1 s; \. E/ z$ [ 这里是当碰到一个bean标签的时候所进行的处理,也既是对bean的定义进行解释,可以看到parseBeanDefinitionElement方法的第一个参数就是bean则个元素,第二个参数表示该bean是否为内置的bean,从这里进行解释的bean都不可能是内置的,所以这里直接以false为参数,打开parseBeanDefinitionElement方法,就可以看到这个方法里就是对bean的内部的解释,也很简单,也不多讲了,呵呵(下班时间已经到了,所以就写这么多了,基本的流程也就这样,没什么特别难的地方。),对了,最后还有一点就是解释完后,bean的定义将会被保存到beanFactory中,这个beanFactory的实现就是XmlBeanFactory了,该beanFactory是在new的时候被传递到reader中的,就是该类中以下这行代码:4 _. ?' Y7 W; f1 N0 e
以下内容为程序代码:, ? Z1 q1 \* v# K6 @
9 L+ a( U u. t* e: R9 f3 r: ? private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); & i0 V4 Z( v# I1 N F! U8 ]) [( I3 |; y: e: ~1 ]6 q