DocumentBuilderFactory factory = createDocumentBuilderFactory(); # P8 v0 i0 r. q
if (logger.isDebugEnabled()) { / E0 n0 v: Z7 T) D
logger.debug("Using JAXP implementation [" + factory + "]");* B' ^8 w1 ]3 o2 F/ n' O8 o( h
}! U* s$ j( I% y' W
DocumentBuilder builder = createDocumentBuilder(factory);* t6 K) @# O2 k( u, ?9 r
Document doc = builder.parse(inputSource);6 F. b( u; O- |$ [# j R
return registerBeanDefinitions(doc, resource);; h" ~! w; x2 d
复制代码
/ g }, j" B( k0 G: N. b- y: H% v
这个方法的目的一目了然,就是为了将资源解释成为Document对象,然后调用registerBeanDefinitions方法,这里不做详细解释,不了解的话请去看看关于JAXP的介绍。接下来我们打开registerBeanDefinitions方法:8 S0 }( q! n$ g A% X/ G. D1 V
以下内容为程序代码:2 E8 I( N3 }+ Y5 O- T y6 s; J
# u- s, P# J3 _! W. V. f public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException {$ O8 C* N# @4 \! ]
XmlBeanDefinitionParser parser = , G2 n1 V8 Z; z" c5 U (XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass); " v% n0 t9 V- t6 J return parser.registerBeanDefinitions(this, doc, resource);" N# S8 w" n' U5 Q N3 V! K6 ^, ]
}4 x, O. p- g5 V2 ?! i
! `+ F+ h3 O4 q2 [
9 P5 V1 g( T: M: ^! Z
这里创建了一个XmlBeanDefinitionParser接口的实现,这个接口的具体类是DefaultXmlBeanDefinitionParser,这个接口很简单,只有registerBeanDefinitions一个方法,这个方法的作用也很明了,就是用来注册Bean的定义的,所以说类和方法的名字一定要起得有意义,这样可以让人一看就大概了解其作用,减少了很多阅读代码的痛苦。废话不多说,我们打开DefaultXmlBeanDefinitionParser的registerBeanDefinitions方法,这个类就是解释XML配置文件的核心类了,打开registerBeanDefinitions方法后我们看到如下代码: . V R8 T0 q' {, Q" I. \以下内容为程序代码:. b, g# i# F- c9 Y/ S L* M3 |
( U6 m( k% | g% b: q/ Y7 z, I
public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource)) T" `4 G( o0 b
throws BeanDefinitionStoreException {6 l" m8 g+ V/ \
' ^, G0 R8 Y4 t/ t- K
this.beanDefinitionReader = reader;) N ] A6 G9 h7 |
this.resource = resource; [6 i' Q/ c3 A& z3 l5 I3 Y3 W2 x: C4 ^) }
logger.debug("Loading bean definitions");6 o) Y: ]9 L3 B4 _1 i; V& D
Element root = doc.getDocumentElement();8 e1 L7 g( X+ ^& w8 O) D
//初始化根元素 + o2 s0 q$ c: o. o; W% W0 }4 N9 z initDefaults(root);# N* b' G! q) }7 ^ w5 }* u2 b
if (logger.isDebugEnabled()) { : k3 ~5 K( V1 @' n1 G2 z logger.debug("Default lazy init '" + getDefaultLazyInit() + "'"); 1 j7 ]9 U* d9 R* e% _ P2 x logger.debug("Default autowire '" + getDefaultAutowire() + "'");# z* t5 ~7 F; K3 x& k
logger.debug("Default dependency check '" + getDefaultDependencyCheck() + "'");4 i% _ N, O+ p6 h; X
}/ C* X+ l: m- T# K1 l8 c6 S3 R
R, e- a9 H$ E; f1 M+ b8 P/ f preProcessXml(root);//一个空方法用于扩展/ i* R/ f- e! b8 d2 O1 B
int beanDefinitionCount = parseBeanDefinitions(root);//解释配置的主要方法3 M0 J+ Z0 n" ] o+ }' w
if (logger.isDebugEnabled()) { / z8 t1 t Q6 U6 O4 R logger.debug("Found " + beanDefinitionCount + " <bean> elements in " + resource); ) B, L2 r* U2 q l } ' h" T8 z5 r j, u& i$ J1 G postProcessXml(root); //一个空方法用于扩展 ( [* N1 [& V! Q4 A$ V4 c: {5 T4 i+ J" ?& K1 l5 v) r5 B/ H
return beanDefinitionCount; t5 N, r9 [$ _: u4 p6 `! R } ( X' t6 G* C; H2 Q z) ]9 g) |/ l! G$ d
! H8 e. D+ O3 `" g. D3 ?0 j$ i 在这个方法当中,主要用于解释定义的有两个方法,一个是initDefaults,一个是parseBeanDefinitions,第一个方法是用来解释根元素的属性的,例如lazy-init, autowire等,而parseBeanDefinitions就是用来解释具体的bean定义了,方法代码如下:$ q! o5 K: I1 Z/ g( u
以下内容为程序代码:; P0 B% [9 L/ e" W
1 R% H' X2 }: O; f' g2 q; n5 h protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException { 2 E2 g; g7 m. P% ?9 A NodeList nl = root.getChildNodes(); 5 N" D. i# p- G& y3 B int beanDefinitionCount = 0;% \2 W. i4 V4 _6 ^9 A Y7 w6 X
for (int i = 0; i < nl.getLength(); i++) {6 ^8 w! M* S3 v# h8 o- O$ G
Node node = nl.item(i); - \% h3 l& P" ^6 J: l! W5 d3 b/ W if (node instanceof Element) {! `: y0 s8 l3 L; I5 }9 A
Element ele = (Element) node;9 {+ H. m6 p! C5 D
if (IMPORT_ELEMENT.equals(node.getNodeName())) { 2 Y- Z4 [1 O8 _ importBeanDefinitionResource(ele); " Z3 P o5 g! W" ]+ R1 A }0 s. C# R4 ^0 X9 I, j
else if (ALIAS_ELEMENT.equals(node.getNodeName())) { , w% W$ o' B1 z' o4 O- k/ i String name = ele.getAttribute(NAME_ATTRIBUTE);3 O8 F$ v: O5 C4 u5 [
String alias = ele.getAttribute(ALIAS_ATTRIBUTE); ) e: p( w( w9 ?$ p N this.beanDefinitionReader.getBeanFactory().registerAlias(name, alias); 9 t5 [1 L+ z' A l6 i$ F, J }% R1 _5 Y# C7 ?1 V( G& A: o
else if (BEAN_ELEMENT.equals(node.getNodeName())) { T* t/ }- Y9 L7 h
beanDefinitionCount++;# q; w" Q- S3 k* j" a O% O% `
BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false);4 t) C* k* f( ]2 _+ t6 ] U$ M
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); - D7 i6 R( @: e, O }& P3 e( V9 a$ O" L2 l
} 0 D1 I# Q X; c- R } ; E) c" o3 ?; s& j$ q3 i return beanDefinitionCount;1 k6 \% J n: `" u
} 3 H5 H y8 ?4 k x% V0 W. j $ v3 K% K9 {6 W; N1 y$ u. ?; ^) t- R& o" w* U# g. J k! ]) q5 ~
其他标签具体如何被解释这里就不多说,相信大家也能看得懂,这里主要讲一下解释bean的的处理,我们注意以下代码:; n! \7 w7 l* ^3 Q
以下内容为程序代码: 6 b6 `8 K) N6 G f- A ; y' R5 h: g) k# c: c% C5 O else if (BEAN_ELEMENT.equals(node.getNodeName())) { ; n( \ S; f- a$ }& C beanDefinitionCount++;3 ?6 ~5 k) P9 Y: a5 d3 ?
BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false);$ e& ]- [/ T, _, f) R
BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); ) Q6 U# e) K$ ^9 Y; r }3 R0 D. | i7 C3 p; M
) m- d) }/ v* P, i
这里是当碰到一个bean标签的时候所进行的处理,也既是对bean的定义进行解释,可以看到parseBeanDefinitionElement方法的第一个参数就是bean则个元素,第二个参数表示该bean是否为内置的bean,从这里进行解释的bean都不可能是内置的,所以这里直接以false为参数,打开parseBeanDefinitionElement方法,就可以看到这个方法里就是对bean的内部的解释,也很简单,也不多讲了,呵呵(下班时间已经到了,所以就写这么多了,基本的流程也就这样,没什么特别难的地方。),对了,最后还有一点就是解释完后,bean的定义将会被保存到beanFactory中,这个beanFactory的实现就是XmlBeanFactory了,该beanFactory是在new的时候被传递到reader中的,就是该类中以下这行代码:( u! B% p- U) Z- o l- _# q
以下内容为程序代码: . A6 O" E1 w6 D/ s0 } d- Z7 w" m% q$ p1 U6 J5 g0 G; X+ L4 [
private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);7 S% h# ]/ L: z8 b( X
! W! y( u+ {' F' p1 T( ^* _
K/ f/ ~0 ?. e- u( P 好了,就这么多了,本文只作为参考,只讲解了如何加载bean定义这块,只作为一个参考,希望对其他朋友能有所帮助吧,因为时间匆忙,有错漏的地方请指正。