Spring中 bean定义的parent属性机制的实现分析
<bean id="transactionProxy01" parent="transactionProxy1"> <property name="target" ref="service01"/> </bean> <bean id="transactionProxy1" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="transactionManager"></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,timeout_6000,-Exception</prop> <prop key="error*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,timeout_20,readOnly,-Exception</prop> <!-- -Exception表示有Exception抛出时,事务回滚. -代表回滚 +就代表提交 --> </props> </property> </bean>
- 一个是解析xml创建出BeanDefinition对象,
- 一个是从beanFactory中 依据BeanDefinition创建出实例
protected void parseBeanDefinitions(Element root, BeanDefinitionParserDelegate delegate) { if (delegate.isDefaultNamespace(root)) { NodeList nl = root.getChildNodes(); for (int i = 0; i < nl.getLength(); i++) { Node node = nl.item(i); if (node instanceof Element) { Element ele = (Element) node; if (delegate.isDefaultNamespace(ele)) { parseDefaultElement(ele, delegate); //对xml中的bean元素挨个做解析 } else { delegate.parseCustomElement(ele); } } } } else { delegate.parseCustomElement(root); } }
protected void processBeanDefinition(Element ele, BeanDefinitionParserDelegate delegate) { //利用delegate的方法 解析出bean元素 beanDefinition对象存放在一个Holder里面 BeanDefinitionHolder bdHolder = delegate.parseBeanDefinitionElement(ele); if (bdHolder != null) { try { //这个是注册 就是把BeanDefinition保存到BeanFactory的BeanDefinitionMap里面去 BeanDefinitionReaderUtils.registerBeanDefinition(bdHolder, getReaderContext().getRegistry()); } } }
public BeanDefinitionHolder parseBeanDefinitionElement(Element ele, BeanDefinition containingBean) { String id = ele.getAttribute(ID_ATTRIBUTE); //获取出bean的id String nameAttr = ele.getAttribute(NAME_ATTRIBUTE); //...省略了一些代码 String beanName = id; //...省略了一些代码 AbstractBeanDefinition beanDefinition = parseBeanDefinitionElement(ele, beanName, containingBean);//解析xml中的bean元素 创建beanDefinition对象 if (beanDefinition != null) { //...省略了一些代码 String[] aliasesArray = StringUtils.toStringArray(aliases); return new BeanDefinitionHolder(beanDefinition, beanName, aliasesArray); } return null; }
public AbstractBeanDefinition parseBeanDefinitionElement( Element ele, String beanName, BeanDefinition containingBean) { this.parseState.push(new BeanEntry(beanName));//SAX解析特有的 都要定义一个stack做辅助 String className = null; if (ele.hasAttribute(CLASS_ATTRIBUTE)) { className = ele.getAttribute(CLASS_ATTRIBUTE).trim(); } try { String parent = null; if (ele.hasAttribute(PARENT_ATTRIBUTE)) { parent = ele.getAttribute(PARENT_ATTRIBUTE); //取出了parent属性的值 } AbstractBeanDefinition bd = createBeanDefinition(className, parent);//创建一个BeanDefinition对象 注意把parent属性传进去了 //后面就是解析bean元素的其他属性 然后set到这个BeanDefinition对象里面去 parseBeanDefinitionAttributes(ele, beanName, containingBean, bd); //...省略了一些代码 return bd; } //...省略了一些代码 finally { this.parseState.pop(); } return null; }
进入BeanDefinitionReaderUtils工具类
public static AbstractBeanDefinition createBeanDefinition( String parentName, String className, ClassLoader classLoader) throws ClassNotFoundException { GenericBeanDefinition bd = new GenericBeanDefinition();//创建一个beanDefinition对象 bd.setParentName(parentName);//把parent属性set进去 if (className != null) { if (classLoader != null) { bd.setBeanClass(ClassUtils.forName(className, classLoader)); } else { bd.setBeanClassName(className); } } return bd; //然后返回beanDefinition对象 }
至此 BeanDefinition是创建完了 可以看到,我们定义parent属性,在创建过程中并没有什么特殊的处理,只是把parent作为一个属性,设置到BeanDefinition对象里面去了
protected <T> T doGetBean( final String name, final Class<T> requiredType, final Object[] args, boolean typeCheckOnly) throws BeansException {
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName); //这里是根据beanName获取到BeanDefinition,parent的处理就是在这里发生的
protected RootBeanDefinition getMergedLocalBeanDefinition(String beanName) throws BeansException { // Quick check on the concurrent map first, with minimal locking. RootBeanDefinition mbd = this.mergedBeanDefinitions.get(beanName); //一开始获取合并的BeanDefinition 肯定是null 之前没有缓存的 if (mbd != null) { return mbd; } //然后先取出原始的transactionProxy01的beanDefinition 注意 这里取出的beanDefinition中 beanName是transactionProxy01,parent是transactionProxy1, //但是beanClass是null //然后执行getMergedBeanDefinition(beanName, getBeanDefinition(beanName)) 准备把parent的beanClass属性拿出来放到子beanBefinition里面去 return getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); }
protected RootBeanDefinition getMergedBeanDefinition( String beanName, BeanDefinition bd, BeanDefinition containingBd) throws BeanDefinitionStoreException { synchronized (this.mergedBeanDefinitions) { RootBeanDefinition mbd = null; // Check with full lock now in order to enforce the same merged instance. if (containingBd == null) { mbd = this.mergedBeanDefinitions.get(beanName); } if (mbd == null) { if (bd.getParentName() == null) { //....省略一些代码 } else { // Child bean definition: needs to be merged with parent. BeanDefinition pbd; try { String parentBeanName = transformedBeanName(bd.getParentName());//取到parent的name if (!beanName.equals(parentBeanName)) { //这个方法获取parent对于的beanDefinition,这个方法里面其实又是调用上一个方法的 //也就是还是进一步调用getMergedBeanDefinition(beanName, getBeanDefinition(beanName)); 是递归的! 用于解决parent还有parent 的情况 //所以这个地方要特别注意的 多层级的parent处理就是这里的递归解决的 pbd = getMergedBeanDefinition(parentBeanName); } else { //....省略一些代码 } } //....省略一些代码 // Deep copy with overridden values. //核心的来了 先用parent 的BeanDefinition为参数,创建了一个新的BeanDefinition 想想都知道就是new了一个新的RootBeanDefinition对象 //然后把parent的BeanDefinition的属性一个一个都set到新的RootBeanDefinition对象里面,相当于深拷贝了 mbd = new RootBeanDefinition(pbd); mbd.overrideFrom(bd);//然后用孩子beanDefinition已有的属性 去覆盖掉parent里继承下来的属性值 } //....省略一些代码 } return mbd; } }
至此,spring处理的parent的方式已经搞清楚了
<bean id="transactionProxy01" parent="transactionProxy1"> <property name="target" ref="service01"/> </bean> <bean id="transactionProxy1" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"> <property name="transactionManager" ref="transactionManager"></property> <property name="transactionAttributes"> <props> <prop key="*">PROPAGATION_REQUIRED,ISOLATION_READ_COMMITTED,timeout_6000,-Exception</prop> <prop key="error*">PROPAGATION_REQUIRED,ISOLATION_DEFAULT,timeout_20,readOnly,-Exception</prop> </props> </property> </bean>
- 我们得到的mbd 就是这样一个BeanDefinition
- 它的beanName是transactionProxy01
- 它的target是service01
- 它的beanClass,以及其他的属性,都和parent的BeanDefinition是相同的
private final Map<String, RootBeanDefinition> mergedBeanDefinitions = new ConcurrentHashMap<String, RootBeanDefinition>(64);
原创博客,转载请注明出处
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。