本文转自“天河聊技术”微信公众号
说在前面
基于注解的spring声明式事务管理源码解析已经完毕了,第一篇文章中提到spring事务管理模式有两种形式一种是proxy,一种是aspectj,基于proxy已经解析完毕了,默认的也是proxy,声明式事务管理配置一种是基于注解,一种是基于xml配置文件的,最后再补充下基于aspectj这种事务模式和基于xml配置的声明式事务管理的源码解析。
正文
基于aspectj的声明事务管理模式源码解析
找到这个方法org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#parse
@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);
进入到这个方法
org.springframework.transaction.config.AnnotationDrivenBeanDefinitionParser#registerTransactionAspect
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));
}
}
进入到这个类
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)));
}
}
下面的逻辑都一样了,都走的是一个事务拦截器拦截事务方法,解析事务属性,开启事务进行提交或者回滚。
说到最后
本次解析仅代表个人见解,仅供参考。
来源:oschina
链接:https://my.oschina.net/u/3775437/blog/1843013