package com.mandui.framework.aspect;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.aop.Advisor;
import org.springframework.aop.aspectj.AspectJExpressionPointcut;
import org.springframework.aop.support.DefaultPointcutAdvisor;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionManager;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.transaction.interceptor.NameMatchTransactionAttributeSource;
import org.springframework.transaction.interceptor.RollbackRuleAttribute;
import org.springframework.transaction.interceptor.RuleBasedTransactionAttribute;
import org.springframework.transaction.interceptor.TransactionAttribute;
import org.springframework.transaction.interceptor.TransactionInterceptor;
@Configuration
@Aspect
public class TransactionConfig {
/**
* 配置切入点,如果配置多个切入点 使用 || 进行拼接
* 范例
* execution(* com.mandui.project.service.impl.*.*(..)) || execution(* com.mandui.test.service.impl.*.*(..))
*/
private static final String AOP_POINTCUT_EXPRESSION = "execution(* com.mandui.project.**.service.*.*(..))";
private static final int TX_METHOD_TIMEOUT = 5000;
@Autowired
private TransactionManager transactionManager;
@Bean
public TransactionInterceptor txAdvice() {
/**事务管理规则,声明具备事务管理的方法名**/
NameMatchTransactionAttributeSource source = new NameMatchTransactionAttributeSource();
/**只读事务,不做更新操作**/
RuleBasedTransactionAttribute readOnlyTx = new RuleBasedTransactionAttribute();
readOnlyTx.setReadOnly(true);
readOnlyTx.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
/**定义事物的隔离级别, PROPAGATION_NOT_SUPPORTED 事务传播级别5,以非事务运行,如果当前存在事务,则把当前事务挂起**/
readOnlyTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_NOT_SUPPORTED);
readOnlyTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
/**当前存在事务就使用当前事务,当前不存在事务就创建一个新的事务**/
RuleBasedTransactionAttribute requiredTx = new RuleBasedTransactionAttribute();
/**抛出异常后执行切点回滚***/
requiredTx.setRollbackRules(Collections.singletonList(new RollbackRuleAttribute(Exception.class)));
requiredTx.setIsolationLevel(TransactionDefinition.ISOLATION_READ_COMMITTED);
/**PROPAGATION_REQUIRED 事务隔离性为1,若当前存在事务,则加入该事务,不存在,则创建一个新的事务,这是默认值**/
requiredTx.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRED);
/**设置事务失效时间,如果超过5秒,则回滚事务**/
requiredTx.setTimeout(TX_METHOD_TIMEOUT);
//Map<String,TransactionAttribute> txMap = new HashMap<String,TransactionAttribute>();
source.addTransactionalMethod("add*", requiredTx);
source.addTransactionalMethod("insert*", requiredTx);
source.addTransactionalMethod("save*", requiredTx);
source.addTransactionalMethod("do*", requiredTx);
source.addTransactionalMethod("create*", requiredTx);
source.addTransactionalMethod("append*", requiredTx);
source.addTransactionalMethod("delete*", requiredTx);
source.addTransactionalMethod("remove*", requiredTx);
source.addTransactionalMethod("clear*", requiredTx);
source.addTransactionalMethod("update*", requiredTx);
source.addTransactionalMethod("modify*", requiredTx);
source.addTransactionalMethod("edit*", requiredTx);
source.addTransactionalMethod("batch*", requiredTx);
source.addTransactionalMethod("exec*", requiredTx);
source.addTransactionalMethod("set*", requiredTx);
source.addTransactionalMethod("get*", readOnlyTx);
source.addTransactionalMethod("query*", readOnlyTx);
source.addTransactionalMethod("list*", readOnlyTx);
source.addTransactionalMethod("count*", readOnlyTx);
source.addTransactionalMethod("find*", readOnlyTx);
source.addTransactionalMethod("load*", readOnlyTx);
source.addTransactionalMethod("search*", readOnlyTx);
TransactionInterceptor txAdvice = new TransactionInterceptor(transactionManager,source);
return txAdvice;
}
@Bean
public Advisor txAdviceAdvisor() {
/**声明切点的面:切面就是通知和切入点的结合,通知和切入点共同定义了关于切面的全部内容,
* 他的功能/在何时和何地完成其功能**/
AspectJExpressionPointcut pointCut = new AspectJExpressionPointcut();
/**声明和设置需要拦截的方法,用切点语言描写**/
pointCut.setExpression(AOP_POINTCUT_EXPRESSION);
/**设置切面 = 切点pointCut + 通知txAdvice***/
return new DefaultPointcutAdvisor(pointCut, txAdvice());
}
}
**
控制台输出**
[23:01:21:561] [INFO] - Bean 'spring.datasource-org.springframework.boot.autoconfigure.jdbc.DataSourceProperties' of type [org.springframework.boot.autoconfigure.jdbc.DataSourceProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:21:565] [INFO] - Bean 'com.alibaba.druid.spring.boot.autoconfigure.stat.DruidFilterConfiguration' of type [com.alibaba.druid.spring.boot.autoconfigure.stat.DruidFilterConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:21:592] [INFO] - Bean 'statFilter' of type [com.alibaba.druid.filter.stat.StatFilter] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:508] [INFO] - {dataSource-1} inited
[23:01:22:508] [INFO] - Bean 'dataSource' of type [com.alibaba.druid.spring.boot.autoconfigure.DruidDataSourceWrapper] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:521] [INFO] - Bean 'org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration' of type [org.springframework.boot.autoconfigure.transaction.TransactionAutoConfiguration] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:527] [INFO] - Bean 'spring.transaction-org.springframework.boot.autoconfigure.transaction.TransactionProperties' of type [org.springframework.boot.autoconfigure.transaction.TransactionProperties] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:532] [INFO] - Bean 'platformTransactionManagerCustomizers' of type [org.springframework.boot.autoconfigure.transaction.TransactionManagerCustomizers] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:536] [INFO] - Bean 'transactionManager' of type [org.springframework.jdbc.support.JdbcTransactionManager] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:537] [INFO] - Bean 'transactionConfig' of type [com.mandui.framework.aspect.TransactionConfig$$EnhancerBySpringCGLIB$$54538598] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:550] [INFO] - Bean 'txAdvice' of type [org.springframework.transaction.interceptor.TransactionInterceptor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)
[23:01:22:551] [INFO] - Bean 'txAdviceAdvisor' of type [org.springframework.aop.support.DefaultPointcutAdvisor] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying)