return registerBeanDefinitions(doc, resource); , l. J7 L) u0 _; j/ m; w
复制代码
" T0 g, h9 b! N& B9 h
4 d$ R# ~9 s$ I9 N! x 这个方法的目的一目了然,就是为了将资源解释成为Document对象,然后调用registerBeanDefinitions方法,这里不做详细解释,不了解的话请去看看关于JAXP的介绍。接下来我们打开registerBeanDefinitions方法:4 P& o% m- m, E' K# ^7 F" [* w
以下内容为程序代码: ) r3 f. T) Q5 }# t& d! H( X . K* e# N/ l+ d" Q: H public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException { ) D$ i8 H; E: u/ g XmlBeanDefinitionParser parser =! Q' d- g- R& S% i& x
(XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass); }: ?4 c; Y v- _
return parser.registerBeanDefinitions(this, doc, resource);# S$ K6 y* p( c. f
} ; d! Z+ b1 J0 }5 S# U$ v : D) g& X0 z3 a* P9 j! b' H8 Q) D1 e/ j. g
这里创建了一个XmlBeanDefinitionParser接口的实现,这个接口的具体类是DefaultXmlBeanDefinitionParser,这个接口很简单,只有registerBeanDefinitions一个方法,这个方法的作用也很明了,就是用来注册Bean的定义的,所以说类和方法的名字一定要起得有意义,这样可以让人一看就大概了解其作用,减少了很多阅读代码的痛苦。废话不多说,我们打开DefaultXmlBeanDefinitionParser的registerBeanDefinitions方法,这个类就是解释XML配置文件的核心类了,打开registerBeanDefinitions方法后我们看到如下代码: 2 n# k7 Z4 H# i" {2 c$ q以下内容为程序代码:" F; {4 N- H) i) A; X
( p5 @9 i7 |, Y$ p& M$ K public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource) . @" R0 e/ j" K5 s' v throws BeanDefinitionStoreException {0 W9 F6 e. h1 @! U
' U2 Z" w$ t; U6 X% r1 p this.beanDefinitionReader = reader;. D# J- p8 X& e0 j) X
this.resource = resource;' {( w4 F& `' i
% \; E( O9 z! q4 r
logger.debug("Loading bean definitions");2 f4 h N8 \+ B5 @
Element root = doc.getDocumentElement();' X5 _( F7 b2 n& e0 j- k( ~
//初始化根元素( Y' B# v$ g0 W0 S, u! H
initDefaults(root);5 F7 y- M O3 j6 k% q1 c& q. o7 Z
if (logger.isDebugEnabled()) { 9 I2 a8 m w: b* d logger.debug("Default lazy init '" + getDefaultLazyInit() + "'"); : A1 _' M+ ?! N logger.debug("Default autowire '" + getDefaultAutowire() + "'"); 3 e: @! h; ^' [4 i logger.debug("Default dependency check '" + getDefaultDependencyCheck() + "'");3 n% U& `- H. }
}/ B, O% P7 Y. z6 g0 C8 q7 V
3 l3 ?; U( q" u& j1 }, L
preProcessXml(root);//一个空方法用于扩展8 `) u) a* B! U4 \$ L! _9 c$ K1 M: M
int beanDefinitionCount = parseBeanDefinitions(root);//解释配置的主要方法' G8 Q- F, t6 N* o* m+ M
if (logger.isDebugEnabled()) {3 a* t3 @6 J5 J. _# n
logger.debug("Found " + beanDefinitionCount + " <bean> elements in " + resource); ) `, H( ^, A% z* y } / z6 ]7 [/ K5 h postProcessXml(root); //一个空方法用于扩展+ u; Q+ |, \! {4 P9 z" @
v$ Q9 y \/ h7 [$ M$ _ return beanDefinitionCount; 7 t' t5 {8 @/ ^# d. n6 W5 K$ p } % ~, m; H5 l2 ^+ e- j& x* b* M; m+ q; w" g+ {
1 ]' d8 {4 O0 A4 h! a/ q' @+ c
在这个方法当中,主要用于解释定义的有两个方法,一个是initDefaults,一个是parseBeanDefinitions,第一个方法是用来解释根元素的属性的,例如lazy-init, autowire等,而parseBeanDefinitions就是用来解释具体的bean定义了,方法代码如下: : x2 _; k2 F' Z, r" V5 B* ]以下内容为程序代码: / w% t5 F6 e( ]1 n8 h; M& T/ y7 n% I0 D/ ?$ T; F2 R, Q; q
protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException {& a# m6 C; ^& a) O
NodeList nl = root.getChildNodes(); : f) n. u8 Y; p6 R! O5 h- J int beanDefinitionCount = 0;& [' j# \, g0 p8 v2 [
for (int i = 0; i < nl.getLength(); i++) { 0 f& T$ E- D( ` e# J) T Node node = nl.item(i);3 k ?0 v- u @2 f+ l
if (node instanceof Element) { 5 T6 `, S9 ?- R Element ele = (Element) node;1 P$ {8 n p3 q6 K, Q8 F& m) r
if (IMPORT_ELEMENT.equals(node.getNodeName())) {6 _8 a! l6 n- [6 e1 a; l, A1 _8 ^# U
importBeanDefinitionResource(ele); 2 t. M2 I, j1 h } % e. D4 g. U) s else if (ALIAS_ELEMENT.equals(node.getNodeName())) {; a& Z' B- p; e- w; R
String name = ele.getAttribute(NAME_ATTRIBUTE); 2 f) N* d0 f K5 e9 k/ v! ] String alias = ele.getAttribute(ALIAS_ATTRIBUTE); 8 g6 D% I, n! G this.beanDefinitionReader.getBeanFactory().registerAlias(name, alias);6 E8 o* `3 `6 G
} / M" j0 p' f, N C. y& L1 K) } else if (BEAN_ELEMENT.equals(node.getNodeName())) {" M, E" q0 z- |& H8 `1 x
beanDefinitionCount++; ) W5 ^# `4 g! J$ _0 ^* A8 R8 ^* f BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false); " A% _! m3 D4 g1 _# k% n BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); * `( d4 M+ x0 T% b% e" f4 R }8 V6 l& a: t( ~
} - `1 G6 f7 ]+ G }4 A7 `$ T+ T! h
return beanDefinitionCount;9 @) j' u! r6 a5 Z. i
} $ P/ I+ N( ?4 K/ A. X& I' o$ n4 O5 m( N! H' j& `
. r/ s+ F$ }2 M/ n3 _# k a, d
其他标签具体如何被解释这里就不多说,相信大家也能看得懂,这里主要讲一下解释bean的的处理,我们注意以下代码:% c: k2 h1 S$ U: M4 ]; p
以下内容为程序代码: ' A7 l7 v; e- {5 s; n( x8 P* |7 S d" }' w1 S1 ^4 Y# ]6 ?% K
else if (BEAN_ELEMENT.equals(node.getNodeName())) { . @. @3 g: h/ z! h- Z$ B' Z beanDefinitionCount++; + o# L6 e1 Z v: I" q) ?, x BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false);1 S+ d( H" F; M/ M
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory());" M" A% e2 R3 [5 _6 \6 }5 z
} 4 ^; L# f& ^+ a @, C+ X# ?2 N2 a* }2 z1 o5 |0 h+ J
这里是当碰到一个bean标签的时候所进行的处理,也既是对bean的定义进行解释,可以看到parseBeanDefinitionElement方法的第一个参数就是bean则个元素,第二个参数表示该bean是否为内置的bean,从这里进行解释的bean都不可能是内置的,所以这里直接以false为参数,打开parseBeanDefinitionElement方法,就可以看到这个方法里就是对bean的内部的解释,也很简单,也不多讲了,呵呵(下班时间已经到了,所以就写这么多了,基本的流程也就这样,没什么特别难的地方。),对了,最后还有一点就是解释完后,bean的定义将会被保存到beanFactory中,这个beanFactory的实现就是XmlBeanFactory了,该beanFactory是在new的时候被传递到reader中的,就是该类中以下这行代码:5 J# ]8 r. \+ X- H
以下内容为程序代码:; i4 C! q& g1 K: L y. V1 A5 Y0 b8 ]7 w
0 o8 `2 S% R- O5 e
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this); ; ]- H0 D' Z+ }2 }! G& M # |" A2 E! E+ m1 d) ?6 \1 M) i; b5 `; ]! P: U* K7 S; C3 Z p
好了,就这么多了,本文只作为参考,只讲解了如何加载bean定义这块,只作为一个参考,希望对其他朋友能有所帮助吧,因为时间匆忙,有错漏的地方请指正。