return registerBeanDefinitions(doc, resource); h. L+ F+ D4 ^) O4 _
复制代码
) n4 n6 ^6 \' H s' N . r8 A: |; V' p. w 这个方法的目的一目了然,就是为了将资源解释成为Document对象,然后调用registerBeanDefinitions方法,这里不做详细解释,不了解的话请去看看关于JAXP的介绍。接下来我们打开registerBeanDefinitions方法:4 M* M* s+ z9 n8 v9 g3 j. R
以下内容为程序代码:' K% P9 a, r# P/ m
) G' V) O6 M! ^* R8 E- E public int registerBeanDefinitions(Document doc, Resource resource) throws BeansException { + l* J. E, ^2 n/ n: F" {0 E' a XmlBeanDefinitionParser parser = ' E. B4 J1 Q* u7 x. t3 o6 S (XmlBeanDefinitionParser) BeanUtils.instantiateClass(this.parserClass); , a$ E. t# M# J3 e" S" a return parser.registerBeanDefinitions(this, doc, resource); ) ?, }- e& c7 L( m$ o! U }9 p7 N8 k0 X2 i8 u
/ o3 q# o- @( O/ j3 |
4 }8 \) }8 S' D4 F4 \1 y 这里创建了一个XmlBeanDefinitionParser接口的实现,这个接口的具体类是DefaultXmlBeanDefinitionParser,这个接口很简单,只有registerBeanDefinitions一个方法,这个方法的作用也很明了,就是用来注册Bean的定义的,所以说类和方法的名字一定要起得有意义,这样可以让人一看就大概了解其作用,减少了很多阅读代码的痛苦。废话不多说,我们打开DefaultXmlBeanDefinitionParser的registerBeanDefinitions方法,这个类就是解释XML配置文件的核心类了,打开registerBeanDefinitions方法后我们看到如下代码:% ~4 A/ c+ L' x, D$ j; g2 t7 T* H
以下内容为程序代码:/ y# ]( v, r% Y% w) W
. Y9 Y; M' v- z: w% I" A
public int registerBeanDefinitions(BeanDefinitionReader reader, Document doc, Resource resource)1 [6 `' k& t S2 m1 @
throws BeanDefinitionStoreException { & }+ r( \4 P9 m) p' a $ `* P/ F. O, N5 U2 W2 G% \, S/ k this.beanDefinitionReader = reader;! o( x( f8 L5 A9 m7 @2 t9 t
this.resource = resource; ( s$ s' W; k& G, n1 I) q. N" b# D8 Z6 Z+ h& a
logger.debug("Loading bean definitions"); # b: a* ?2 P: r" a5 O$ m Element root = doc.getDocumentElement(); " q3 U( F1 z' j" B //初始化根元素 ( U7 L3 c4 j- C initDefaults(root); - V# e& v# }% r% e: ]0 a if (logger.isDebugEnabled()) {: m- [* \& {- A+ s2 U
logger.debug("Default lazy init '" + getDefaultLazyInit() + "'");9 z" S- v" T% ~" L& ?5 C1 s
logger.debug("Default autowire '" + getDefaultAutowire() + "'");9 G1 m' C8 F3 H
logger.debug("Default dependency check '" + getDefaultDependencyCheck() + "'"); 6 J @# h% w' ? } : ~& }( m) `+ c; ]* v" c! D+ B, [% }0 P; o
preProcessXml(root);//一个空方法用于扩展2 o- O) v4 e1 ]! p; K5 q
int beanDefinitionCount = parseBeanDefinitions(root);//解释配置的主要方法: G" y. ]/ j! Y
if (logger.isDebugEnabled()) { ; Z! e4 O+ G. z7 b logger.debug("Found " + beanDefinitionCount + " <bean> elements in " + resource); ) O' I. P" U1 q, N } 5 g/ N& `4 V. x. m( N) U postProcessXml(root); //一个空方法用于扩展. C4 \, z/ o/ N) q. r4 E' h9 U
5 }' S. d" Y, d2 E( X$ F
return beanDefinitionCount;; [3 Y' H& u, u4 K
} / l0 l0 \! T0 U& t& O: a# L2 G , P" G9 k1 d P6 [: x6 Q 1 m) |2 R4 U3 K1 L7 w1 k7 I 在这个方法当中,主要用于解释定义的有两个方法,一个是initDefaults,一个是parseBeanDefinitions,第一个方法是用来解释根元素的属性的,例如lazy-init, autowire等,而parseBeanDefinitions就是用来解释具体的bean定义了,方法代码如下: # ?2 Q V8 @9 x0 p/ B$ Z* H以下内容为程序代码: 0 |# _# C4 i7 t/ i# ^" i3 r! N. |# c; H1 x# V
protected int parseBeanDefinitions(Element root) throws BeanDefinitionStoreException {' g* _" f! h9 _+ u3 }1 u
NodeList nl = root.getChildNodes();) [7 t. ^* ]8 ?: [3 Y; S( }* Q+ \4 Z
int beanDefinitionCount = 0; 3 W x* y* l; K; l2 g" G for (int i = 0; i < nl.getLength(); i++) { 0 p4 g: }9 _' c" |, m+ j5 R. E! H! U Node node = nl.item(i); . d# R7 N2 L/ l2 f& K$ S2 X if (node instanceof Element) { 5 W) p" ^5 r3 k8 C- S# V3 C Element ele = (Element) node; $ r" M+ R' q: D9 t* v' g3 l; v if (IMPORT_ELEMENT.equals(node.getNodeName())) { 6 }6 s6 ~& T, D4 x1 K: j/ H9 w importBeanDefinitionResource(ele); * j/ `8 J4 m; G( X2 X5 Y6 k }' B9 ]3 T) x1 F9 x, J
else if (ALIAS_ELEMENT.equals(node.getNodeName())) { 0 {4 P9 p5 v. N8 G9 [2 g String name = ele.getAttribute(NAME_ATTRIBUTE); 7 p- ~* }0 B: ]" _0 S String alias = ele.getAttribute(ALIAS_ATTRIBUTE); : `/ a2 M8 t0 X this.beanDefinitionReader.getBeanFactory().registerAlias(name, alias);3 V! h$ N- \1 E
}4 |% T5 T8 C) W3 a! F% X
else if (BEAN_ELEMENT.equals(node.getNodeName())) { 6 E, X- n1 B) Q$ }! d beanDefinitionCount++;7 Q3 x6 f' W% i: E7 [
BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false); & }/ k+ \" K* q- y' d C$ A) n4 h, o BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory()); - M4 t2 g5 J8 A7 ] }$ A* F+ v/ w3 }- D" x+ @
} 3 m& [. Z5 R% ` } . ]! W4 f/ r0 i return beanDefinitionCount; $ `3 l- X" ]: @2 J: j& e }- U; H8 k& |8 _# e3 u, W
5 Q' z' Q/ s1 ^4 F5 j6 S) E2 y
/ s! E: b T8 t6 i; y: R 其他标签具体如何被解释这里就不多说,相信大家也能看得懂,这里主要讲一下解释bean的的处理,我们注意以下代码:: {4 p/ _. H% p# f
以下内容为程序代码: $ r/ @2 f+ l8 q8 s, I) B P " t, A, p. V% V. [2 k& { @ else if (BEAN_ELEMENT.equals(node.getNodeName())) { 1 A- t$ n* Z) W beanDefinitionCount++;8 |- Z6 w$ {( k) |2 h) x5 u- P
BeanDefinitionHolder bdHolder = parseBeanDefinitionElement(ele, false); # r) O. p3 U' y" I: F BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, this.beanDefinitionReader.getBeanFactory());& k5 U* A$ x4 ^, _7 G3 j
}% f0 ?9 s5 }5 a ^9 Z# @: k
. V, H8 L) ]: ^4 ]) t ? 这里是当碰到一个bean标签的时候所进行的处理,也既是对bean的定义进行解释,可以看到parseBeanDefinitionElement方法的第一个参数就是bean则个元素,第二个参数表示该bean是否为内置的bean,从这里进行解释的bean都不可能是内置的,所以这里直接以false为参数,打开parseBeanDefinitionElement方法,就可以看到这个方法里就是对bean的内部的解释,也很简单,也不多讲了,呵呵(下班时间已经到了,所以就写这么多了,基本的流程也就这样,没什么特别难的地方。),对了,最后还有一点就是解释完后,bean的定义将会被保存到beanFactory中,这个beanFactory的实现就是XmlBeanFactory了,该beanFactory是在new的时候被传递到reader中的,就是该类中以下这行代码:( G# d) J6 _: v5 {/ R
以下内容为程序代码: + p- H/ s4 R0 m d3 g8 z" `& o9 q9 ^ private final XmlBeanDefinitionReader reader = new XmlBeanDefinitionReader(this);; h* f) M2 | \. k; J: b3 |