本文转自“天河聊技术”微信公众号spring
说在前面微信
基于注解的spring声明式事务管理源码解析已经完毕了,第一篇文章中提到spring事务管理模式有两种形式一种是proxy,一种是aspectj,基于proxy已经解析完毕了,默认的也是proxy,声明式事务管理配置一种是基于注解,一种是基于xml配置文件的,最后再补充下基于aspectj这种事务模式和基于xml配置的声明式事务管理的源码解析。app
正文ide
基于aspectj的声明事务管理模式源码解析ui
找到这个方法org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#parsethis
@Override @Nullable public BeanDefinition parse(Element element, ParserContext parserContext) { // 注册事务监听器工厂 registerTransactionalEventListenerFactory(parserContext); // 获取模式属性 String mode = element.getAttribute("mode"); if ("aspectj".equals(mode)) { // mode="aspectj" registerTransactionAspect(element, parserContext); } else { // mode="proxy" AopAutoProxyConfigurer.configureAutoProxyCreator(element, parserContext); } return null; }
if ("aspectj".equals(mode)) { // mode="aspectj" registerTransactionAspect(element, parserContext);
进入到这个方法spa
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#registerTransactionAspectorm
private void registerTransactionAspect(Element element, ParserContext parserContext) { String txAspectBeanName = TransactionManagementConfigUtils.TRANSACTION_ASPECT_BEAN_NAME; String txAspectClassName = TransactionManagementConfigUtils.TRANSACTION_ASPECT_CLASS_NAME; if (!parserContext.getRegistry().containsBeanDefinition(txAspectBeanName)) { RootBeanDefinition def = new RootBeanDefinition(); def.setBeanClassName(txAspectClassName); def.setFactoryMethodName("aspectOf"); // 注册事务管理器到bean定义中 registerTransactionManager(element, def); // 注册AnnotationTransactionAspect bean定义 parserContext.registerBeanComponent(new BeanComponentDefinition(def, txAspectBeanName)); } }
进入到这个类xml
org.springframework.transaction.aspectj.AnnotationTransactionAspect对象
public aspect AnnotationTransactionAspect extends AbstractTransactionAspect { public AnnotationTransactionAspect() { // 初始化注解事务资源 super(new AnnotationTransactionAttributeSource(false)); } /** * Matches the execution of any public method in a type with the Transactional将类型中的任何公共方法的执行与事务匹配 * annotation, or any subtype of a type with the Transactional annotation.注释,或具备事务注释的类型的任何子类型。 */ private pointcut executionOfAnyPublicMethodInAtTransactionalType() : execution(public * ((@Transactional *)+).*(..)) && within(@Transactional *); /** * Matches the execution of any method with the Transactional annotation.将任何方法的执行与事务注释匹配。 */ private pointcut executionOfTransactionalMethod() : execution(@Transactional * *(..)); /** * Definition of pointcut from super aspect - matched join points从超方面匹配的链接点定义切入点 * will have Spring transaction management applied.将应用Spring事务管理。 */ protected pointcut transactionalMethodExecution(Object txObject) : (executionOfAnyPublicMethodInAtTransactionalType() || executionOfTransactionalMethod() ) && this(txObject); }
基于aop标签配置的声明式事务源码解析
找到这个方法
org.springframework.transaction.config.TxAdviceBeanDefinitionParser#doParse
@Override protected void doParse(Element element, ParserContext parserContext, BeanDefinitionBuilder builder) { // 构造事务管理器对象 builder.addPropertyReference("transactionManager", TxNamespaceHandler.getTransactionManagerName(element)); // 获取<tx:attributes>子节点 List<Element> txAttributes = DomUtils.getChildElementsByTagName(element, ATTRIBUTES_ELEMENT); // 只能有一个<tx:attributes>节点 if (txAttributes.size() > 1) { parserContext.getReaderContext().error( "Element <attributes> is allowed at most once inside element <advice>", element); } else if (txAttributes.size() == 1) { // Using attributes source. Element attributeSourceElement = txAttributes.get(0); // 解析<tx:attributes>标签 RootBeanDefinition attributeSourceDefinition = parseAttributeSource(attributeSourceElement, parserContext); builder.addPropertyValue("transactionAttributeSource", attributeSourceDefinition); } else { // Assume annotations source. builder.addPropertyValue("transactionAttributeSource", new RootBeanDefinition("org.springframework.transaction.annotation.AnnotationTransactionAttributeSource")); } }
private RootBeanDefinition parseAttributeSource(Element attrEle, ParserContext parserContext) { // 获取<tx:method子节点 List<Element> methods = DomUtils.getChildElementsByTagName(attrEle, METHOD_ELEMENT); ManagedMap<TypedStringValue, RuleBasedTransactionAttribute> transactionAttributeMap = new ManagedMap<>(methods.size()); transactionAttributeMap.setSource(parserContext.extractSource(attrEle)); for (Element methodEle : methods) { // 获取name属性 String name = methodEle.getAttribute(METHOD_NAME_ATTRIBUTE); TypedStringValue nameHolder = new TypedStringValue(name); nameHolder.setSource(parserContext.extractSource(methodEle)); RuleBasedTransactionAttribute attribute = new RuleBasedTransactionAttribute(); // 获取事务传播机制 String propagation = methodEle.getAttribute(PROPAGATION_ATTRIBUTE); // 获取事务隔离级别 String isolation = methodEle.getAttribute(ISOLATION_ATTRIBUTE); // 获取事务超时参数 String timeout = methodEle.getAttribute(TIMEOUT_ATTRIBUTE); // 获取事务只读属性 String readOnly = methodEle.getAttribute(READ_ONLY_ATTRIBUTE); if (StringUtils.hasText(propagation)) { attribute.setPropagationBehaviorName(RuleBasedTransactionAttribute.PREFIX_PROPAGATION + propagation); } if (StringUtils.hasText(isolation)) { attribute.setIsolationLevelName(RuleBasedTransactionAttribute.PREFIX_ISOLATION + isolation); } if (StringUtils.hasText(timeout)) { try { attribute.setTimeout(Integer.parseInt(timeout)); } catch (NumberFormatException ex) { parserContext.getReaderContext().error("Timeout must be an integer value: [" + timeout + "]", methodEle); } } if (StringUtils.hasText(readOnly)) { attribute.setReadOnly(Boolean.valueOf(methodEle.getAttribute(READ_ONLY_ATTRIBUTE))); } List<RollbackRuleAttribute> rollbackRules = new LinkedList<>(); if (methodEle.hasAttribute(ROLLBACK_FOR_ATTRIBUTE)) { // 获取事务回滚的异常配置 String rollbackForValue = methodEle.getAttribute(ROLLBACK_FOR_ATTRIBUTE); addRollbackRuleAttributesTo(rollbackRules,rollbackForValue); } if (methodEle.hasAttribute(NO_ROLLBACK_FOR_ATTRIBUTE)) { // 获取不回滚事务的异常类型 String noRollbackForValue = methodEle.getAttribute(NO_ROLLBACK_FOR_ATTRIBUTE); addNoRollbackRuleAttributesTo(rollbackRules,noRollbackForValue); } attribute.setRollbackRules(rollbackRules); transactionAttributeMap.put(nameHolder, attribute); } RootBeanDefinition attributeSourceDefinition = new RootBeanDefinition(NameMatchTransactionAttributeSource.class); attributeSourceDefinition.setSource(parserContext.extractSource(attrEle)); attributeSourceDefinition.getPropertyValues().add("nameMap", transactionAttributeMap); return attributeSourceDefinition; }
private void addRollbackRuleAttributesTo(List<RollbackRuleAttribute> rollbackRules, String rollbackForValue) { // 能够配置多个异常,用,分开 String[] exceptionTypeNames = StringUtils.commaDelimitedListToStringArray(rollbackForValue); for (String typeName : exceptionTypeNames) { rollbackRules.add(new RollbackRuleAttribute(StringUtils.trimWhitespace(typeName))); } } private void addNoRollbackRuleAttributesTo(List<RollbackRuleAttribute> rollbackRules, String noRollbackForValue) { // 能够配置多个异常,用,分开 String[] exceptionTypeNames = StringUtils.commaDelimitedListToStringArray(noRollbackForValue); for (String typeName : exceptionTypeNames) { rollbackRules.add(new NoRollbackRuleAttribute(StringUtils.trimWhitespace(typeName))); } }
下面的逻辑都同样了,都走的是一个事务拦截器拦截事务方法,解析事务属性,开启事务进行提交或者回滚。
说到最后
本次解析仅表明我的看法,仅供参考。