美文网首页
Spring Bean加载探究(三)

Spring Bean加载探究(三)

作者: IceBins | 来源:发表于2017-10-18 13:05 被阅读0次

上文说到在解析具体的bean时候,会走到不同的分支,可能是parseDefaultElement,也可能是parseCustomElement,接下来看parseDefaultElement的机制。

this.parseDefaultElement(ele, delegate);

默认标签

首先进入到parseDefaultElement(Element ele, BeanDefinitionParserDelegate delegate)

if(delegate.nodeNameEquals(ele, "import")) {
            this.importBeanDefinitionResource(ele);
        } else if(delegate.nodeNameEquals(ele, "alias")) {
            this.processAliasRegistration(ele);
        } else if(delegate.nodeNameEquals(ele, "bean")) {
            this.processBeanDefinition(ele, delegate); // 查看这个
        } else if(delegate.nodeNameEquals(ele, "beans")) {
            this.doRegisterBeanDefinitions(ele);
        }

可见, 主要对四种类型的node进行解析,分别是import、alias、bean、beans进行解析

  • bean解析
  1. 首先进入到processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) 中, 委托BeanDefinitionDelegate类的parseBeanDefinitionElement 方法进行元素解析, 返回BeanDefinitionHolder实例。
    • 获得element的id,name等参数
    • 对name使用tokenizer截断(,;), 然后把这些截断的字符串加到alias中
    • 如果id未定义但是alias数组不为空,则把alias中的第一个元素作为beanName, 否则, id就是beanName
    • 然后检查beanName以及alias的唯一性 checkNameUniqueness
    • parseBeanDefinitionElement: 获得BeanDefinition的定义
  2. 接上文所述,执行BeanDefinitionParserDelegate的parseBeanDefinitionElement(Element ele, String beanName, BeanDefinition containingBean)函数
  • 把当前的解析状态放在parseState栈中
  • 初始化:解析class属性和parent属性
  • 创建BeanDefinition对象: 初始化beanClassName 和 parent属性
  • 解析bean的一些属性:parseBeanDefinitionAttributes, scope、abstract、lazy-init、autowire、dependency-check、depends-on、autowire-candidate、primary、init-method、destroy-method、factory-method、factory-bean等属性
  • 解析子元素metaData:解析诸如如下的情形
<bean id="as" class = "">
  <meta key="key1" value="val1"/>
  <meta key="key2" value= "val2" />
</bean>
  • 配置lookup方法,(获取器注入) 这个方法主要在某些特定的情况下比较有用
举个例子:
有基类Base和Der1, Der2, 其中Der1和Der2都重写了Base类的work函数
然后有一个AbstractFactory类
abstract class AbstractFactory{
......
abstract Base getBase();
......
}
然后在context.xml中配置
<bean id="absBase" class="xxx.xxx.AbstractBase">
   <lookup-method name="getBase" bean="der1"/>
</bean>
<bean id="der1" class="xxxx.xxx.Der1"/>

获得absBase bean之后,调用起getBase,就会得到Der1对象, 而随着业务逻辑的变化,可在这个bean中配置其他的Base继承类来实现,高度解耦

  • 解析子元素replace-method:类似上面,提供一个替换函数的解决方案
首先定义一个Bean A, 然后定义一个CallBack 实现MethodReplacer,实现其reimplement函数,然后在险要替换函数的bean上加一个<replace-method标签,设置函数名称name以及replacer用来指定替换bean

相关文章

网友评论

      本文标题:Spring Bean加载探究(三)

      本文链接:https://www.haomeiwen.com/subject/ceehtxtx.html