Spring 源码解析(八)自定命名空间标签解析器 BeanDefinitionParser

自定义命名空间的每个标签都需要有去对应的解析器,且解析器需要实现BeanDefinitionParser,在parse方法中,解析将来在Spring配置文件中出现的标签元素。进入TxAdviceBeanDefinitionParser的parse方法(在org.springframework.beans.factory.xml.AbstractBeanDefinitionParser类实现)

 //org.springframework.beans.factory.xml.AbstractBeanDefinitionParser
1
@Override 2 public final BeanDefinition parse(Element element, ParserContext parserContext) { 3 AbstractBeanDefinition definition = parseInternal(element, parserContext);//类定义 4 if (definition != null && !parserContext.isNested()) { 5 try { 6 String id = resolveId(element, definition, parserContext); 7 if (!StringUtils.hasText(id)) { 8 parserContext.getReaderContext().error( 9 "Id is required for element '" + parserContext.getDelegate().getLocalName(element) 10 + "' when used as a top-level tag", element); 11 } 12 String[] aliases = new String[0]; 13 String name = element.getAttribute(NAME_ATTRIBUTE); 14 if (StringUtils.hasLength(name)) { 15 aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name)); 16 } 17 BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases); 18 registerBeanDefinition(holder, parserContext.getRegistry()); 19 if (shouldFireEvents()) { 20 BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder); 21 postProcessComponentDefinition(componentDefinition); 22 parserContext.registerComponent(componentDefinition); 23 } 24 } 25 catch (BeanDefinitionStoreException ex) { 26 parserContext.getReaderContext().error(ex.getMessage(), element); 27 return null; 28 } 29 } 30 return definition; 31 }

第3行,解析标签为类定义AbstractBeanDefinition实例,跟进方法(org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser类实现)

 //org.springframework.beans.factory.xml.AbstractSingleBeanDefinitionParser
1
/** 2 * Creates a {@link BeanDefinitionBuilder} instance for the 3 * {@link #getBeanClass bean Class} and passes it to the 4 * {@link #doParse} strategy method. 5 * @param element the element that is to be parsed into a single BeanDefinition 6 * @param parserContext the object encapsulating the current state of the parsing process 7 * @return the BeanDefinition resulting from the parsing of the supplied {@link Element} 8 * @throws IllegalStateException if the bean {@link Class} returned from 9 * {@link #getBeanClass(org.w3c.dom.Element)} is {@code null} 10 * @see #doParse 11 */ 12 @Override 13 protected final AbstractBeanDefinition parseInternal(Element element, ParserContext parserContext) { 14 BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(); 15 String parentName = getParentName(element); 16 if (parentName != null) { 17 builder.getRawBeanDefinition().setParentName(parentName); 18 } 19 Class<?> beanClass = getBeanClass(element);//获取bean的类型Class对象 20 if (beanClass != null) { 21 builder.getRawBeanDefinition().setBeanClass(beanClass); 22 } 23 else { 24 String beanClassName = getBeanClassName(element);//获取类名 25 if (beanClassName != null) { 26 builder.getRawBeanDefinition().setBeanClassName(beanClassName); 27 } 28 } 29 builder.getRawBeanDefinition().setSource(parserContext.extractSource(element)); 30 if (parserContext.isNested()) { 31 // Inner bean definition must receive same scope as containing bean. 32 builder.setScope(parserContext.getContainingBeanDefinition().getScope()); 33 } 34 if (parserContext.isDefaultLazyInit()) { 35 // Default-lazy-init applies to custom bean definitions as well. 36 builder.setLazyInit(true); 37 } 38 doParse(element, parserContext, builder); 39 return builder.getBeanDefinition(); 40 }

第19行,查找bean的类型即Class对象,跟进方法(在org.springframework.transaction.config.TxAdviceBeanDefinitionParser类中实现)

//org.springframework.transaction.config.TxAdviceBeanDefinitionParser
1
@Override 2 protected Class<?> getBeanClass(Element element) { 3 return TransactionInterceptor.class; 4 }

<tx:advice/>标签解析,最后得到了一个className为TransactionInterceptor的BeanDefinition并注册。

我们看下TransactionInterceptor类的定义

 1 /**
 2  * AOP Alliance MethodInterceptor for declarative transaction
 3  * management using the common Spring transaction infrastructure
 4  * ({@link org.springframework.transaction.PlatformTransactionManager}).
 5  *
 6  * <p>Derives from the {@link TransactionAspectSupport} class which
 7  * contains the integration with Spring's underlying transaction API.
 8  * TransactionInterceptor simply calls the relevant superclass methods
 9  * such as {@link #invokeWithinTransaction} in the correct order.
10  *
11  * <p>TransactionInterceptors are thread-safe.
12  *
13  * @author Rod Johnson
14  * @author Juergen Hoeller
15  * @see TransactionProxyFactoryBean
16  * @see org.springframework.aop.framework.ProxyFactoryBean
17  * @see org.springframework.aop.framework.ProxyFactory
18  */
19 @SuppressWarnings("serial")
20 public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
21        //省略代码
22 }

TransactionInterceptor实现了MethodInterceptor接口,所以这个类本质是一个Spring AOP 的advice,也就不难理解事物的配置能通过Spring AOP产生作用了。在此不分析事物处理的细节部分,对于Spring AOP需要读者有一定了解,在此也不在赘述。

★★★★★基于 <tx> 的事务管理示例配置文件★★★★★

 1 <beans......>
 2 ......
 3 <bean id="bankService" class="footmark.spring.core.tx.declare.namespace.BankServiceImpl">
 5    <property name="bankDao" ref="bankDao"/>
 6 </bean>
 7 <tx:advice id="bankAdvice" transaction-manager="transactionManager">
 8    <tx:attributes>
 9        <tx:method name="transfer" propagation="REQUIRED"/>
10    </tx:attributes>
11 </tx:advice>
12  
13 <aop:config>
14    <aop:pointcut id="bankPointcut" expression="execution(* *.transfer(..))"/>
15    <aop:advisor advice-ref="bankAdvice" pointcut-ref="bankPointcut"/>
16 </aop:config>
17 ......
18 </beans>

 

posted @ 2018-04-09 15:28  jintian315  阅读(342)  评论(0编辑  收藏  举报