tx标签与spring的结合的流程

tx配置实例

<?xml version="1.0" encoding="UTF-8"?>
<!--suppress XmlUnusedNamespaceDeclaration -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx"
       xmlns:p="http://www.springframework.org/schema/p" xmlns:cache="http://www.springframework.org/schema/cache"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
          http://www.springframework.org/schema/aop
          http://www.springframework.org/schema/aop/spring-aop-3.1.xsd
          http://www.springframework.org/schema/tx
          http://www.springframework.org/schema/tx/spring-tx-3.1.xsd
          http://www.springframework.org/schema/cache
          http://www.springframework.org/schema/cache/spring-cache-3.1.xsd"
       default-lazy-init="true">
    <import resource="druid.xml"></import>
    <bean id="transactionManager"
          class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource" />
    </bean>

    <!--基于 <tx> 和 <aop> 命名空间的声明式事务-->
    <!--  配置事务传播特性 -->
    <tx:advice id="TestAdvice" transaction-manager="transactionManager">
        <tx:attributes>
            <tx:method name="save*" propagation="REQUIRED"/>
            <tx:method name="del*" propagation="REQUIRED"/>
            <tx:method name="update*" propagation="REQUIRED"/>
            <tx:method name="add*" propagation="REQUIRED"/>
            <tx:method name="find*" propagation="REQUIRED"/>
            <tx:method name="get*" propagation="REQUIRED"/>
            <tx:method name="apply*" propagation="REQUIRED"/>
        </tx:attributes>
    </tx:advice>

    <tx:annotation-driven/>

    <!--  配置参与事务的类 -->
    <aop:config>
        <aop:pointcut id="allTestServiceMethod" expression="execution(* com.qunar.fresh2017.service.*.*(..))"/>
        <aop:advisor pointcut-ref="allTestServiceMethod" advice-ref="TestAdvice" />
    </aop:config>

</beans>

分析

  • 根据xmlns:tx="http://www.springframework.org/schema/tx"找到tx标签的处理函数,对应到spring-tx的jar包下的META-INF/Resource Bundle ‘spring’/spring-handlers:http://www.springframework.org/schema/tx=org.springframework.transaction.config.TxNamespaceHandler;xsi:schemaLocation定义了解析相关的规范,在org/springframework/transaction/config下。
  • TxNamespaceHandler在org/springframework/transaction/config目录下,继承链:public class TxNamespaceHandler extends NamespaceHandlerSupport
  • 实现方法如下,调用底层的方法把不同标签的解析类注入到parsers中()
 //TxNamespaceHandler
 @Override
 public void init() {
   registerBeanDefinitionParser("advice", new TxAdviceBeanDefinitionParser());
   registerBeanDefinitionParser("annotation-driven", new AnnotationDrivenBeanDefinitionParser());
   registerBeanDefinitionParser("jta-transaction-manager", new JtaTransactionManagerBeanDefinitionParser());
 }

//NamespaceHandlerSupport
 protected final void registerBeanDefinitionParser(String elementName, BeanDefinitionParser parser) {
   this.parsers.put(elementName, parser);
 }
//TxAdviceBeanDefinitionParser
private static final String METHOD_ELEMENT = "method";
private static final String METHOD_NAME_ATTRIBUTE = "name";
private static final String ATTRIBUTES_ELEMENT = "attributes";
private static final String TIMEOUT_ATTRIBUTE = "timeout";
private static final String READ_ONLY_ATTRIBUTE = "read-only";
private static final String PROPAGATION_ATTRIBUTE = "propagation";
private static final String ISOLATION_ATTRIBUTE = "isolation";
private static final String ROLLBACK_FOR_ATTRIBUTE = "rollback-for";
private static final String NO_ROLLBACK_FOR_ATTRIBUTE = "no-rollback-for";
protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) {.....}
  • AbstractBeanDefinitionParser解析xml得到相应的bean实例,供给后续使用,继承链:
    • public abstract class AbstractBeanDefinitionParser implements BeanDefinitionParser
    • public abstract class AbstractSingleBeanDefinitionParser extends AbstractBeanDefinitionParser
    • public abstract class AbstractBeanDefinitionParser implements BeanDefinitionParser
//AbstractBeanDefinitionParser
/** Constant for the "id" attribute */
public static final String ID_ATTRIBUTE = "id";

/** Constant for the "name" attribute */
public static final String NAME_ATTRIBUTE = "name";

public final BeanDefinition parse(Element element, ParserContext parserContext) {
        AbstractBeanDefinition definition = parseInternal(element, parserContext);
        if (definition != null && !parserContext.isNested()) {
            try {
                String id = resolveId(element, definition, parserContext);
                if (!StringUtils.hasText(id)) {
                    parserContext.getReaderContext().error(
                            "Id is required for element '" + parserContext.getDelegate().getLocalName(element)
                                    + "' when used as a top-level tag", element);
                }
                String[] aliases = null;
                if (shouldParseNameAsAliases()) {
                    String name = element.getAttribute(NAME_ATTRIBUTE);
                    if (StringUtils.hasLength(name)) {
                        aliases = StringUtils.trimArrayElements(StringUtils.commaDelimitedListToStringArray(name));
                    }
                }
                BeanDefinitionHolder holder = new BeanDefinitionHolder(definition, id, aliases);
                registerBeanDefinition(holder, parserContext.getRegistry());
                if (shouldFireEvents()) {
                    BeanComponentDefinition componentDefinition = new BeanComponentDefinition(holder);
                    postProcessComponentDefinition(componentDefinition);
                    parserContext.registerComponent(componentDefinition);
                }
            }
            catch (BeanDefinitionStoreException ex) {
                parserContext.getReaderContext().error(ex.getMessage(), element);
                return null;
            }
        }
        return definition;
    }

思考

  • pasers的调用者是谁,在什么环节解析解析bean?注解的解析方式与xml的异同?
  • TxAdviceBeanDefinitionParser中protected Class<?> getBeanClass(Element element) {
    return TransactionInterceptor.class;
    }
    方法的作用,与parsers的联系。
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值