本文将对spring aop的实现、jdk动态代理、Aspectj实现原理、spring数据库事务底层原理一一分析
一、AOP常用概念:
1、pointcut 切入点 也就是方法 spring会通过设置的pointcut来match要拦截的方法
2、joinpoint 连接点 还是方法 在哪里aop 最终还是会通过joinpoint执行原方法
3、advice 通知|增强 我们知道的@before @after @around这些注解都是advice
4、advisor = advice+pointcut 我们设置的advice最终都会被spring封装成advisor
5、weaving 织入 这是一个动作 将增强方法织入到原方法上
6、aspect 点连成面
7、target 目标类 通过反射调用目标类的目标方法
二、AOP的实现
2.1、实现1 通过ProxyFactoryBean
概念太抽象 用具体例子来描述 我们先通过ProxyFactoryBean 一个最简单的示例来完成一个aop
public class MainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(MyConfig.class);
IproxyMethod proxyMethod = (IproxyMethod) context.getBean("myProxyFactoryBean");
proxyMethod.test();
}
}
@Configuration
public class MyConfig {
// 被代理对象
@Bean
public ProxyMethod proxyMethod() {
return new ProxyMethod();
}
// Advice 方式
@Bean
public MyBeforeAdvice myBeforeAdvice(){
return new MyBeforeAdvice();
}
// Interceptor方式 , 可以理解为环绕通知
@Bean
public MyIntercepter myIntercepter() {
return new MyIntercepter();
}
/**
* FactoryBean方式单个: ProxyFactoryBean
* 缺点:
* 1、只能指定单一的Bean的AOP,
* 2、拦截器的粒度只控制到了类级别,类中所有的方法都进行了拦截
*
*/
@Bean
public ProxyFactoryBean myProxyFactoryBean(){
ProxyFactoryBean proxyFactoryBean=new ProxyFactoryBean();
proxyFactoryBean.setInterceptorNames("myBeforeAdvice","myIntercepter"); // 根据指定的顺序执行
proxyFactoryBean.setTarget(proxyMethod());
return proxyFactoryBean;
}
}
public class MyBeforeAdvice implements MethodBeforeAdvice {
@Override
public void before(Method method, Object[] args, Object target) throws Throwable {
System.out.println("target方法[" + method.getName() + "] 前置增强 ,参数" + Arrays.asList(args));
}
}
public class MyIntercepter implements MethodInterceptor {
@Override
public Object invoke(MethodInvocation invocation) throws Throwable {
System.out.println(getClass()+"方法执行前");
Object ret=invocation.proceed();
System.out.println(getClass()+"方法执行后");
return ret;
}
}
public interface IproxyMethod {
public void test();
public void test1();
}
public class ProxyMethod implements IproxyMethod{
public void test(){
System.out.println("test执行");
}
public void test1(){
System.out.println("test1执行");
}
}
上面例子中
target即目标类是proxyMethod()
advice 增强方法有两个:myBeforeAdvice()和myIntercepter() 查看源码 我们可以发现 Interceptor其实是继承了Advice 也就是说Interceptor其实就是特殊的advice
pointcut 切点我们并没有看到指定 也就是说上面的代理类会为所有方法创建 也是弊端之一
joinpoint :test()和test1()方法及joinpoint
该示例缺点明显
只能指定单一的bean对象
因为没有设置pointcut 所有类的所有方法都被代理
2.2、实现2 通过Advisor来设置
以NameMatchMethodPointcutAdvisor为例 advisor = advice+pointcut 设置就完事了
@Configuration
public class AdviserConfig {
// 被代理对象
@Bean
public IproxyMethod proxyMethod() {
return new ProxyMethod();
}
// Advice 方式
@Bean
public MyBeforeAdvice myBeforeAdvice(){
return new MyBeforeAdvice();
}
/**
* Advisor 种类很多 不一一赘述
*/
@Bean
public NameMatchMethodPointcutAdvisor myAspectAdvisor() {
NameMatchMethodPointcutAdvisor advisor=new NameMatchMethodPointcutAdvisor();//创建advisor
advisor.setAdvice(myBeforeAdvice());//设置advice增强方法
advisor.setMappedNames("test");//切点方法 设置pointcut切入点 按方法名匹配的切入点
return advisor;
}
/**
* 此时设置的interceptor是一个advisor
* 缺点:还是只能代理单一的bean
* @return
*/
@Bean
public ProxyFactoryBean myProxyFactoryBean(){
ProxyFactoryBean myService=new ProxyFactoryBean();
myService.setInterceptorNames("myAspectAdvisor");
myService.setTarget(proxyMethod());
return myService;
}
}
spring提供了很多的adivsor 可以通过不同的方式去设置pointcut
此时我们可以自己设置pointcut的了 但是还是只能针对单一的bean
2.3、实现3 通过beanPostProcessor来设置
@Configuration
public class BeanPostProcessorConfig {
// 被代理对象
@Bean
public IproxyMethod proxyMethod() {
return new ProxyMethod();
}
// Interceptor方式 , 可以理解为环绕通知
@Bean
public MyIntercepter myIntercepter() {
return new MyIntercepter();
}
@Bean
public BeanNameAutoProxyCreator autoProxyCreator() {
BeanNameAutoProxyCreator beanNameAutoProxyCreator = new BeanNameAutoProxyCreator();
//设置要创建代理的那些Bean的名字 以proxy开头的beanname
beanNameAutoProxyCreator.setBeanNames("proxy*");
//设置拦截链名字(这些拦截器是有先后顺序的)
beanNameAutoProxyCreator.setInterceptorNames("myIntercepter");
return beanNameAutoProxyCreator;
}
}
此时我们可以设置多个bean 并且可以设置自定义的advice增强
2.4、实现4 通过xml来设置
<?xml version="1.0" encoding="UTF-8"?>
<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"
xsi:schemaLocation="http://www.springframework.org/schema/beans
https://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
https://www.springframework.org/schema/aop/spring-aop.xsd">
<!-- target 目标对象 -->
<bean id="proxyMethod" class="com.lgj.spring.aop.earlyaop.ProxyMethod"></bean>
<!-- 增强具体实现 -->
<bean id="myInterceptor" class="com.lgj.spring.aop.xml.MyInterceptor"></bean>
<aop:config>
<!-- 设置pointcut 路径下所有方法 -->
<aop:pointcut expression="execution(* com.lgj.spring.aop.earlyaop.*.*(..) )" id="pointcut1" />
<!-- aspect 配置切面 指向的是自定义的增强 -->
<aop:aspect id="logAdvice" ref="myInterceptor">
<!-- 增强adivice before就会封装成前置增强 -->
<aop:before method="before" pointcut-ref="pointcut1" />
</aop:aspect>
</aop:config>
</beans>
public class XmlAopMain {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("classpath:springAop.xml");
IproxyMethod iproxyMethod = applicationContext.getBean(IproxyMethod.class);
iproxyMethod.test();
}
}
public class MyInterceptor {
public void before(){
System.out.println("前置增强");
}
}
2.5、实现5 通过@aspectj注解来设置
示例代码:
@Component
@Aspect
public class MyAspectj {
//EXECUtion可以是个范围 制定方法 方法名参数等等
@Pointcut("execution(* com.lgj.spring.aop.aspectj.service.*.*(..))")
public void pointCutPoint() {
}
@Before("pointCutPoint()")
public void before() {
System.out.println("before");
}
@After("pointCutPoint()")
public void after(){
System.out.println("after");
}
@Around("pointCutPoint()")
public Object around(ProceedingJoinPoint joinPoint){//joinPoint-》MethodInvocationProceedingJoinPoint
System.out.println("around 前置执行");
try {
Object proceed = joinPoint.proceed(joinPoint.getArgs());
System.out.println("around 后置执行");
return proceed;
} catch (Throwable e) {
System.out.println("around 异常执行");
return null;
} finally {
System.out.println("around finally执行");
}
}
}
@Configuration
@ComponentScan("com.lgj.spring.aop.aspectj")
@EnableAspectJAutoProxy(proxyTargetClass =false)
public class AspectConfig {
}
public class TestAspectMain {
public static void main(String[] args) {
// TODO Auto-generated method stub
ApplicationContext ac = new AnnotationConfigApplicationContext(AspectConfig.class);
MyService myService = ac.getBean(MyService.class);
myService.test();
}
}
public interface MyService {
void test();
}
@Service
public class MyServiceImpl implements MyService {
@Override
public void test() {
System.out.println("执行test");
}
}
三、AOP的原理前置知识 动态代理
我们都知道spring实现动态代理的两种方式:jdk动态代理以及cglib
以jdk动态代理为例:增强类即JdkDynamicAopProxy
org.springframework.aop.framework.JdkDynamicAopProxy#getProxy(java.lang.ClassLoader)
public Object getProxy(@Nullable ClassLoader classLoader) {//获取代理类
if (logger.isTraceEnabled()) {
logger.trace("Creating JDK dynamic proxy: " + this.advised.getTargetSource());
}
Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);//返回代理类 增强方法传的this 所以直接查看该类的invoke即可
}
查看动态代理生成的类发现 就是调用其invoke方法:
![](https://i-blog.csdnimg.cn/blog_migrate/0b2735913658d47b7df538d4e825b566.png)
查看其增强方法invoke方法:
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
Object oldProxy = null;
boolean setProxyContext = false;
TargetSource targetSource = this.advised.targetSource;
Object target = null;
try {
//1、参数合法性校验
if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
// The target does not implement the equals(Object) method itself.
return equals(args[0]);
}
else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
// The target does not implement the hashCode() method itself.
return hashCode();
}
else if (method.getDeclaringClass() == DecoratingProxy.class) {
// There is only getDecoratedClass() declared -> dispatch to proxy config.
return AopProxyUtils.ultimateTargetClass(this.advised);
}
else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
method.getDeclaringClass().isAssignableFrom(Advised.class)) {
// Service invocations on ProxyConfig with the proxy config...
return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
}
Object retVal;
if (this.advised.exposeProxy) {
// Make invocation available if necessary.
oldProxy = AopContext.setCurrentProxy(proxy);
setProxyContext = true;
}
// Get as late as possible to minimize the time we "own" the target,
// in case it comes from a pool.
target = targetSource.getTarget();//目标类
Class<?> targetClass = (target != null ? target.getClass() : null);
// 2、拿到advice链 后续会嵌套执行其invoke方法
List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
// Check whether we have any advice. If we don't, we can fallback on direct
// reflective invocation of the target, and avoid creating a MethodInvocation.
if (chain.isEmpty()) {
// We can skip creating a MethodInvocation: just invoke the target directly
// Note that the final invoker must be an InvokerInterceptor so we know it does
// nothing but a reflective operation on the target, and no hot swapping or fancy proxying.
Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
}
else {
//3、创建反射方法调用类
MethodInvocation invocation =
new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
// 4、执行其proceed方法
retVal = invocation.proceed();
}
// Massage return value if necessary.
Class<?> returnType = method.getReturnType();
if (retVal != null && retVal == target &&
returnType != Object.class && returnType.isInstance(proxy) &&
!RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
// Special case: it returned "this" and the return type of the method
// is type-compatible. Note that we can't help if the target sets
// a reference to itself in another returned object.
retVal = proxy;
}
else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
throw new AopInvocationException(
"Null return value from advice does not match primitive return type for: " + method);
}
return retVal;
}
finally {
if (target != null && !targetSource.isStatic()) {
// Must have come from TargetSource.
targetSource.releaseTarget(target);
}
if (setProxyContext) {
// Restore old proxy.
AopContext.setCurrentProxy(oldProxy);
}
}
}
重要的三个步骤:
1、参数合法性校验
2、拿到advice组成的chain链
3、通过ReflectiveMethodInvocation调用其proceed方法
重要方法:
getInterceptorsAndDynamicInterceptionAdvice 进入代理类的代理方法之前,通过pointcut来匹配当前方式是否需要增强
invocation.proceed执行interceptor的chain 继而反射执行目标方法
查看getInterceptorsAndDynamicInterceptionAdvice方法:
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Method method, @Nullable Class<?> targetClass) {
MethodCacheKey cacheKey = new MethodCacheKey(method);
List<Object> cached = this.methodCache.get(cacheKey);
if (cached == null) {
cached = this.advisorChainFactory.getInterceptorsAndDynamicInterceptionAdvice(
this, method, targetClass);//通过工厂获取advice chain
this.methodCache.put(cacheKey, cached);
}
return cached;
}
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(//转换成interceptor list
Advised config, Method method, @Nullable Class<?> targetClass) {
// This is somewhat tricky... We have to process introductions first,
// but we need to preserve order in the ultimate list.
AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
Advisor[] advisors = config.getAdvisors();//拿到所有advisor
List<Object> interceptorList = new ArrayList<>(advisors.length);//装合适的adivice
Class<?> actualClass = (targetClass != null ? targetClass : method.getDeclaringClass());
Boolean hasIntroductions = null;
for (Advisor advisor : advisors) {//遍历advisor
if (advisor instanceof PointcutAdvisor) {//aspectj的 advice相关注解包装类即进入
// Add it conditionally.
PointcutAdvisor pointcutAdvisor = (PointcutAdvisor) advisor;
// 1、先进行类级别上的匹配 很多自定义的advisor之前已经过滤了 isPreFiltered为true
if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
boolean match;
if (mm instanceof IntroductionAwareMethodMatcher) {//IntroductionAwareMethodMatcher类型 比如aspectj的pointcut:AspectJExpressionPointcut
if (hasIntroductions == null) {
hasIntroductions = hasMatchingIntroductions(advisors, actualClass);
}
match = ((IntroductionAwareMethodMatcher) mm).matches(method, actualClass, hasIntroductions);
}
else {
//2、在进行方法级别上的匹配 扩展点2
match = mm.matches(method, actualClass);
}
if (match) {//方法匹配成功了
//3、拿到advisor对应的Advice增强器集合 或者是通过适配器 适配成合适的interceptor
MethodInterceptor[] interceptors = registry.getInterceptors(advisor);//注册器获取interceptor 所有注册的advisor拿到interceptor
if (mm.isRuntime()) {
// Creating a new object instance in the getInterceptors() method
// isn't a problem as we normally cache created chains.
for (MethodInterceptor interceptor : interceptors) {
interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
}
}
else {
//4、装入集合中
interceptorList.addAll(Arrays.asList(interceptors));
}
}
}
}
else if (advisor instanceof IntroductionAdvisor) {//IntroductionAdvisor实现
IntroductionAdvisor ia = (IntroductionAdvisor) advisor;
if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
else {//spring自己的
Interceptor[] interceptors = registry.getInterceptors(advisor);
interceptorList.addAll(Arrays.asList(interceptors));
}
}
return interceptorList;
}
org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry#getInterceptors
public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
List<MethodInterceptor> interceptors = new ArrayList<>(3);
Advice advice = advisor.getAdvice();
//1、直接实现了MethodInterceptor的advice 直接添加进去
if (advice instanceof MethodInterceptor) {
interceptors.add((MethodInterceptor) advice);
}
//2、否则会通过适配器来 装饰成对应的interceptor
for (AdvisorAdapter adapter : this.adapters) {//adapters初始化有三个
if (adapter.supportsAdvice(advice)) {
interceptors.add(adapter.getInterceptor(advisor));
}
}
if (interceptors.isEmpty()) {
throw new UnknownAdviceTypeException(advisor.getAdvice());
}
//3、返回对应的interceptors
return interceptors.toArray(new MethodInterceptor[0]);
}
直接查看ReflectiveMethodInvocation.proceed方法
org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
public Object proceed() throws Throwable {//jdk动态代理进入
// We start with an index of -1 and increment early.
/**
* currentInterceptorIndex-当前下标 默认为-1 使用前+1 从0开始
* 满足条件代表代表 chain执行完毕 执行目标方法 递归调用
*/
if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
return invokeJoinpoint();//执行目标方法 通过目标类和目标方法反射执行
}
Object interceptorOrInterceptionAdvice =
this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);//从0开始 拿到
if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
// Evaluate dynamic method matcher here: static part will already have
// been evaluated and found to match.
InterceptorAndDynamicMethodMatcher dm =
(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
Class<?> targetClass = (this.targetClass != null ? this.targetClass : this.method.getDeclaringClass());
if (dm.methodMatcher.matches(this.method, targetClass, this.arguments)) {
return dm.interceptor.invoke(this);//入参是this 执行interceptor的invoke方法
}
else {
// Dynamic matching failed.
// Skip this interceptor and invoke the next in the chain.
return proceed();
}
}
else {
// It's an interceptor, so we just invoke it: The pointcut will have
// been evaluated statically before this object was constructed.
/**
* 常见的interceptor
* 可以是相关的Advisor 比如NameMatchMethodPointcutAdvisor 最后还是会拿到设置的advice包装成advisor
* 可以是MethodInterceptor实现
* 可以是advice 支持如下三种
* MethodBeforeAdviceAdapter
* AfterReturningAdviceAdapter
* ThrowsAdviceAdapter
*/
return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);//执行davice的invoke方法
}
}
分析proceed方法:
1、嵌套调用chain里面的advice对象的invoke增强方法
2、 直至完成chain的调用 反射执行目标类的目标方法
所以我们知道如果要实现springAOP 那我们必须要准备一个Advisor ,
其中Advisor包含 advice(重写invoke方法实现增强逻辑)和pointcut(重写match匹配目标方法和目标类) 、target目标类、joinpoint (目标方法)
我们自定义的advice 需要重写invoke方法 实现增强逻辑
四、@EnableAspectJAutoProxy实现原理
1、通过import注解最终注入了一个beanPostProcessor:AnnotationAwareAspectJAutoProxyCreator
2、AnnotationAwareAspectJAutoProxyCreator继承了AbstractAutoProxyCreator 重写了相关方法 最终在创建动态代理之前找到相关advisor
接下来看是怎么找到这个advisor 怎么封装的advice和pointcut的
先看AnnotationAwareAspectJAutoProxyCreator类图
![](https://i-blog.csdnimg.cn/blog_migrate/a3920d5a12c79ab51fcbed66c5b5a089.png)
其中的org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization方法就是动态代理的关键
![](https://i-blog.csdnimg.cn/blog_migrate/d49847d094f9e522992e1a70c9221484.png)
AnnotationAwareAspectJAutoProxyCreator重写了shouldSkip方法
org.springframework.aop.aspectj.autoproxy.AspectJAwareAdvisorAutoProxyCreator#shouldSkip
@Override
protected boolean shouldSkip(Class<?> beanClass, String beanName) {
//1、找到候选的advisor集合
List<Advisor> candidateAdvisors = findCandidateAdvisors();
for (Advisor advisor : candidateAdvisors) {
if (advisor instanceof AspectJPointcutAdvisor &&
((AspectJPointcutAdvisor) advisor).getAspectName().equals(beanName)) {
return true;//合法的就返回true
}
}
return super.shouldSkip(beanClass, beanName);
}
查看方法org.springframework.aop.aspectj.annotation.AnnotationAwareAspectJAutoProxyCreator#findCandidateAdvisors
//这个方法会被调用两次 包括下面分析的方法都是会调用两次
//第一次是AbstractAutoProxyCreator#postProcessBeforeInstantiation 会提前找到advisor缓存起来
//第二次是AbstractAutoProxyCreator#postProcessAfterInstantiation 拿到advisor直接用
protected List<Advisor> findCandidateAdvisors() {
// 1、找实现了Advisor接口的Advisor 我们这边没有
List<Advisor> advisors = super.findCandidateAdvisors();
// Build Advisors for all AspectJ aspects in the bean factory.
if (this.aspectJAdvisorsBuilder != null) {//在initBeanFactory中被创建
//2、创建AspectJ的advisor
advisors.addAll(this.aspectJAdvisorsBuilder.buildAspectJAdvisors());
}
return advisors;
}
org.springframework.aop.aspectj.annotation.BeanFactoryAspectJAdvisorsBuilder#buildAspectJAdvisors
public List<Advisor> buildAspectJAdvisors() {
List<String> aspectNames = this.aspectBeanNames;//查看缓存中是否有 第二次进来就有了
if (aspectNames == null) {//第一次进来没有的情况下
synchronized (this) {
aspectNames = this.aspectBeanNames;
if (aspectNames == null) {
List<Advisor> advisors = new ArrayList<>();
aspectNames = new ArrayList<>();
//3、找到所有实现了Object的bean对象 也就是所有bean对象
String[] beanNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Object.class, true, false);
for (String beanName : beanNames) {
if (!isEligibleBean(beanName)) {
continue;
}
Class<?> beanType = this.beanFactory.getType(beanName);
if (beanType == null) {
continue;
}
//4、找到标注了@Aspect注解的bean对象
if (this.advisorFactory.isAspect(beanType)) {
aspectNames.add(beanName);//添加到缓存中
AspectMetadata amd = new AspectMetadata(beanType, beanName);//包装aspectj的bean对象
if (amd.getAjType().getPerClause().getKind() == PerClauseKind.SINGLETON) {
MetadataAwareAspectInstanceFactory factory =
new BeanFactoryAspectInstanceFactory(this.beanFactory, beanName);
//5、通过advisor工厂创建advisor对象
List<Advisor> classAdvisors = this.advisorFactory.getAdvisors(factory);
if (this.beanFactory.isSingleton(beanName)) {
this.advisorsCache.put(beanName, classAdvisors);
}
else {
this.aspectFactoryCache.put(beanName, factory);
}
advisors.addAll(classAdvisors);
}
else {
// Per target or per this.
if (this.beanFactory.isSingleton(beanName)) {
throw new IllegalArgumentException("Bean with name '" + beanName +
"' is a singleton, but aspect instantiation model is not singleton");
}
MetadataAwareAspectInstanceFactory factory =
new PrototypeAspectInstanceFactory(this.beanFactory, beanName);
this.aspectFactoryCache.put(beanName, factory);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
}
this.aspectBeanNames = aspectNames;//设置到缓存
return advisors;
}
}
}
if (aspectNames.isEmpty()) {
return Collections.emptyList();
}
List<Advisor> advisors = new ArrayList<>();
for (String aspectName : aspectNames) {
List<Advisor> cachedAdvisors = this.advisorsCache.get(aspectName);
if (cachedAdvisors != null) {
advisors.addAll(cachedAdvisors);
}
else {
MetadataAwareAspectInstanceFactory factory = this.aspectFactoryCache.get(aspectName);
advisors.addAll(this.advisorFactory.getAdvisors(factory));
}
}
return advisors;
}
org.springframework.aop.aspectj.annotation.ReflectiveAspectJAdvisorFactory#getAdvisors
public List<Advisor> getAdvisors(MetadataAwareAspectInstanceFactory aspectInstanceFactory) {
Class<?> aspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();//@Aspect注解对应的类
String aspectName = aspectInstanceFactory.getAspectMetadata().getAspectName();//beanName
validate(aspectClass);/验证class
// We need to wrap the MetadataAwareAspectInstanceFactory with a decorator
// so that it will only instantiate once.
MetadataAwareAspectInstanceFactory lazySingletonAspectInstanceFactory =
new LazySingletonAspectInstanceFactoryDecorator(aspectInstanceFactory);
List<Advisor> advisors = new ArrayList<>();
//找到非PointCut注解的所有方法 比如@Before @After声明的注解之类的方法 遍历 生成advisor对象
for (Method method : getAdvisorMethods(aspectClass)) {
//创建包装成adivsor对象 找pointcut
Advisor advisor = getAdvisor(method, lazySingletonAspectInstanceFactory, advisors.size(), aspectName);
if (advisor != null) {
advisors.add(advisor);
}
}
// 延迟初始化 否
if (!advisors.isEmpty() && lazySingletonAspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {
Advisor instantiationAdvisor = new SyntheticInstantiationAdvisor(lazySingletonAspectInstanceFactory);
advisors.add(0, instantiationAdvisor);
}
// Find introduction fields. 找到生命式的代理@DeclareParents注解
for (Field field : aspectClass.getDeclaredFields()) {
Advisor advisor = getDeclareParentsAdvisor(field);
if (advisor != null) {
advisors.add(advisor);
}
}
return advisors;
}
//创建advisor对象并创建pointcut对象
public Advisor getAdvisor(Method candidateAdviceMethod, MetadataAwareAspectInstanceFactory aspectInstanceFactory,
int declarationOrderInAspect, String aspectName) {
validate(aspectInstanceFactory.getAspectMetadata().getAspectClass());
AspectJExpressionPointcut expressionPointcut = getPointcut(//拿到对应的pointcut
candidateAdviceMethod, aspectInstanceFactory.getAspectMetadata().getAspectClass());
if (expressionPointcut == null) {
return null;
}
//封装成advisor对象
return new InstantiationModelAwarePointcutAdvisorImpl(expressionPointcut, candidateAdviceMethod,
this, aspectInstanceFactory, declarationOrderInAspect, aspectName);
}
org.springframework.aop.aspectj.annotation.InstantiationModelAwarePointcutAdvisorImpl#InstantiationModelAwarePointcutAdvisorImpl
public InstantiationModelAwarePointcutAdvisorImpl(AspectJExpressionPointcut declaredPointcut,
Method aspectJAdviceMethod, AspectJAdvisorFactory aspectJAdvisorFactory,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
this.declaredPointcut = declaredPointcut;
this.declaringClass = aspectJAdviceMethod.getDeclaringClass();
this.methodName = aspectJAdviceMethod.getName();
this.parameterTypes = aspectJAdviceMethod.getParameterTypes();
this.aspectJAdviceMethod = aspectJAdviceMethod;
this.aspectJAdvisorFactory = aspectJAdvisorFactory;
this.aspectInstanceFactory = aspectInstanceFactory;
this.declarationOrder = declarationOrder;
this.aspectName = aspectName;
if (aspectInstanceFactory.getAspectMetadata().isLazilyInstantiated()) {//延迟加载
// Static part of the pointcut is a lazy type.
Pointcut preInstantiationPointcut = Pointcuts.union(
aspectInstanceFactory.getAspectMetadata().getPerClausePointcut(), this.declaredPointcut);
// Make it dynamic: must mutate from pre-instantiation to post-instantiation state.
// If it's not a dynamic pointcut, it may be optimized out
// by the Spring AOP infrastructure after the first evaluation.
this.pointcut = new PerTargetInstantiationModelPointcut(
this.declaredPointcut, preInstantiationPointcut, aspectInstanceFactory);
this.lazy = true;
}
else {//单例
// A singleton aspect.
this.pointcut = this.declaredPointcut;//设置pointcut
this.lazy = false;
this.instantiatedAdvice = instantiateAdvice(this.declaredPointcut);//实例化advice
}
}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {//实例化advice对象
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);//通过工厂方法获取advise
return (advice != null ? advice : EMPTY_ADVICE);
}
private Advice instantiateAdvice(AspectJExpressionPointcut pointcut) {
Advice advice = this.aspectJAdvisorFactory.getAdvice(this.aspectJAdviceMethod, pointcut,
this.aspectInstanceFactory, this.declarationOrder, this.aspectName);//通过工厂方法获取advise
return (advice != null ? advice : EMPTY_ADVICE);
}
public Advice getAdvice(Method candidateAdviceMethod, AspectJExpressionPointcut expressionPointcut,
MetadataAwareAspectInstanceFactory aspectInstanceFactory, int declarationOrder, String aspectName) {
Class<?> candidateAspectClass = aspectInstanceFactory.getAspectMetadata().getAspectClass();
validate(candidateAspectClass);
//1、判断该方法的注解是否属于aspect定义的这些注解
AspectJAnnotation<?> aspectJAnnotation =
AbstractAspectJAdvisorFactory.findAspectJAnnotationOnMethod(candidateAdviceMethod);//aspectj相关advise注解
if (aspectJAnnotation == null) {//不是即返回
return null;
}
// If we get here, we know we have an AspectJ method.
// Check that it's an AspectJ-annotated class 类不是Aspect注解声明的类
if (!isAspect(candidateAspectClass)) {
throw new AopConfigException("Advice must be declared inside an aspect type: " +
"Offending method '" + candidateAdviceMethod + "' in class [" +
candidateAspectClass.getName() + "]");
}
if (logger.isDebugEnabled()) {
logger.debug("Found AspectJ method: " + candidateAdviceMethod);
}
AbstractAspectJAdvice springAdvice;
//根据不同的注解创建adivce 重写了不同的invoke方法 被advisor chain调用
switch (aspectJAnnotation.getAnnotationType()) {
case AtPointcut://pointcut注解
if (logger.isDebugEnabled()) {
logger.debug("Processing pointcut '" + candidateAdviceMethod.getName() + "'");
}
return null;
case AtAround://around注解
springAdvice = new AspectJAroundAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtBefore://before注解
springAdvice = new AspectJMethodBeforeAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfter://after注解
springAdvice = new AspectJAfterAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
break;
case AtAfterReturning://afterReturn
springAdvice = new AspectJAfterReturningAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterReturning afterReturningAnnotation = (AfterReturning) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterReturningAnnotation.returning())) {
springAdvice.setReturningName(afterReturningAnnotation.returning());
}
break;
case AtAfterThrowing:
springAdvice = new AspectJAfterThrowingAdvice(
candidateAdviceMethod, expressionPointcut, aspectInstanceFactory);
AfterThrowing afterThrowingAnnotation = (AfterThrowing) aspectJAnnotation.getAnnotation();
if (StringUtils.hasText(afterThrowingAnnotation.throwing())) {
springAdvice.setThrowingName(afterThrowingAnnotation.throwing());
}
break;
default:
throw new UnsupportedOperationException(
"Unsupported advice type on method: " + candidateAdviceMethod);
}
// Now to configure the advice...
springAdvice.setAspectName(aspectName);
springAdvice.setDeclarationOrder(declarationOrder);
String[] argNames = this.parameterNameDiscoverer.getParameterNames(candidateAdviceMethod);
if (argNames != null) {
springAdvice.setArgumentNamesFromStringArray(argNames);
}
springAdvice.calculateArgumentBindings();
return springAdvice;
}
最终我们创建的advisor是InstantiationModelAwarePointcutAdvisorImpl
上面我们看到了pointcut是声明成AspectJExpressionPointcut
advice对象:我们看到不同的注解创建了不同advice对象
查看org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary源码:
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
return bean;
}
if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
return bean;
}
//1、shouldSkip创建好了advisor对象 缓存起来
if (isInfrastructureClass(bean.getClass()) || shouldSkip(bean.getClass(), beanName)) {
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
// 2、拿到或者创建advice
Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
if (specificInterceptors != DO_NOT_PROXY) {
this.advisedBeans.put(cacheKey, Boolean.TRUE);
//3、创建动态代理
Object proxy = createProxy(
bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
this.proxyTypes.put(cacheKey, proxy.getClass());
return proxy;
}
this.advisedBeans.put(cacheKey, Boolean.FALSE);
return bean;
}
创建动态三个步骤
shouldSkip创建好了advisor对象 缓存起来 前面已经分析到了
getAdvicesAndAdvisorsForBean拿到或者创建advice 下面重点分析
3、创建动态代理
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
protected Object[] getAdvicesAndAdvisorsForBean(
Class<?> beanClass, String beanName, @Nullable TargetSource targetSource) {
List<Advisor> advisors = findEligibleAdvisors(beanClass, beanName);//找到合法的advisors对象
if (advisors.isEmpty()) {
return DO_NOT_PROXY;
}
return advisors.toArray();
}
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//1、findCandidateAdvisors方法在before方法中执行过并缓存起来 advisor即InstantiationModelAwarePointcutAdvisorImpl
List<Advisor> candidateAdvisors = findCandidateAdvisors();//找到候选的advisor 也就是用户自定义的advisor 并create这个bean
//2、通过pointcut去判断这个advisor是否匹配
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//判断是否匹配
extendAdvisors(eligibleAdvisors);//扩展的advisor
if (!eligibleAdvisors.isEmpty()) {
//3、对advisor进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);//对advisor进行排序
}
return eligibleAdvisors;
}
这个findAdvisorsThatCanApply 会先对类级别注解进行匹配 然后再对方法级别进行匹配
总结起来@Aspectj原理:
1、通过import注解注入一个beanPostProcessor:AnnotationAwareAspectJAutoProxyCreator且该类实现了动态代理的核心类AbstractAutoProxyCreator,重写其相关方法 来发现和创建advisor
2、创建advisor的同时 创建pointcut(AspectJExpressionPointcut)以及advice
Pointcut.class, Around.class, Before.class, After.class, AfterReturning.class, AfterThrowing.class标注了这些注解的方法最后都封装成一个advice增强器 最终通过反射调用相关方法执行
3、通过切点表达式来match匹配需要代理的方法
五、spring事务@EnableTransactionManagement实现原理
以数据库事务为例:
public class TransactionMainTest {
public static void main(String[] args) {
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(TransactionConfig.class);
ITransService transService = (ITransService) context.getBean(ITransService.class);
transService.pay();
}
}
@EnableTransactionManagement
@ComponentScan("com.lgj.spring.aop.transaction")
public class TransactionConfig {
@Bean
public DataSource dataSource() {
DruidDataSource dataSource = new DruidDataSource();
dataSource.setUsername("root");
dataSource.setPassword("root");
dataSource.setUrl("jdbc:mysql://localhost:3306/test?serverTimezone=UTC&characterEncoding=UTF-8&allowMultiQueries=true&allowPublicKeyRetrieval=true&useSSL=false");
dataSource.setDriverClassName("com.mysql.jdbc.Driver");
return dataSource;
}
@Bean
public JdbcTemplate jdbcTemplate(DataSource dataSource) {
return new JdbcTemplate(dataSource);
}
@Bean
public PlatformTransactionManager transactionManager(DataSource dataSource) {
return new DataSourceTransactionManager(dataSource);
}
}
@Transactional(rollbackFor=Exception.class)
public interface ITransService {
void pay();
}
@Service
public class TransServiceImpl implements ITransService{
@Autowired
JdbcTemplate jdbcTemplate;
@Override
public void pay() {
jdbcTemplate.execute("insert into test(column1) values('testlgj')");
int i =5/0;//异常 sql回滚
}
}
从示例代码可知 sql insert语句因异常回滚 spring事务也是借助aop完成此操作
数据库开启事务 即设置连接为手动提交,try catch捕获异常 根据异常结果判断是否提交事务:
connection.setAutoCommit(false);
从上面aop的例子中 我们知道 spring要想实现aop
必须实现自己的advisor、advice(interceptor)、以及joinpoint
1、EnableTransactionManagement注解引入TransactionManagementConfigurationSelector
![](https://i-blog.csdnimg.cn/blog_migrate/7ede1fd97d8a0885e5503bbd09aff0a1.png)
2、import能帮我们注入bean
查看org.springframework.transaction.annotation.TransactionManagementConfigurationSelector#selectImports
protected String[] selectImports(AdviceMode adviceMode) {
switch (adviceMode) {
case PROXY:
return new String[] {AutoProxyRegistrar.class.getName(),//注入了一个事务的beanpostprocessor
ProxyTransactionManagementConfiguration.class.getName()};//注入了一个配置类 引入了一个advisor
case ASPECTJ:
return new String[] {determineTransactionAspectClass()};
default:
return null;
}
}
其中AutoProxyRegistrar实现了ImportBeanDefinitionRegistrar 帮助我们注入一个beanDefinition对象:
1、InfrastructureAdvisorAutoProxyCreator 该类也是一个BeanPostProcessor 通过bpp创建代理类并校验advisor的合法性
ProxyTransactionManagementConfiguration类 帮我们注入了以下几个东西:
2、advisor:BeanFactoryTransactionAttributeSourceAdvisor 内置了一个poincut:TransactionAttributeSourcePointcut 也就是利用TransactionAttributeSource 来扫描事务注解
3、Advice:TransactionInterceptor 实现事务增强逻辑 放最后说
4、TransactionAttributeSource:扫描事务注解
这四个类一个个分析:
InfrastructureAdvisorAutoProxyCreator 具体的事情都是父类在干 它没干什么事 只是对advisor的合法性做了一个校验 校验了advisor的角色
public class InfrastructureAdvisorAutoProxyCreator extends AbstractAdvisorAutoProxyCreator {
@Nullable
private ConfigurableListableBeanFactory beanFactory;
@Override
protected void initBeanFactory(ConfigurableListableBeanFactory beanFactory) {//子类实现
super.initBeanFactory(beanFactory);
this.beanFactory = beanFactory;//初始化一个beanFactory
}
@Override
protected boolean isEligibleAdvisorBean(String beanName) {//合法advisor的bean 方法重写
return (this.beanFactory != null && this.beanFactory.containsBeanDefinition(beanName) &&//beanFactory不为空 true beanfactory包含该bd
this.beanFactory.getBeanDefinition(beanName).getRole() == BeanDefinition.ROLE_INFRASTRUCTURE);//该bd的角色要对得上
}
}
BeanFactoryTransactionAttributeSourceAdvisor 内置pointcut:TransactionAttributeSourcePointcut
public class BeanFactoryTransactionAttributeSourceAdvisor extends AbstractBeanFactoryPointcutAdvisor {
@Nullable
private TransactionAttributeSource transactionAttributeSource;//AnnotationTransactionAttributeSource
private final TransactionAttributeSourcePointcut pointcut = new TransactionAttributeSourcePointcut() {//内置pointcut
@Override
@Nullable
protected TransactionAttributeSource getTransactionAttributeSource() {
return transactionAttributeSource;//设置完属性 真真用到pointcut时 会创建TransactionAttributeSourcePointcut
}
};
public void setTransactionAttributeSource(TransactionAttributeSource transactionAttributeSource) {
this.transactionAttributeSource = transactionAttributeSource;
}
...
}
TransactionAttributeSourcePointcut
设置了类过滤器
重写了类matchs方法
重写了方法matchs方法
protected TransactionAttributeSourcePointcut() {
setClassFilter(new TransactionAttributeSourceClassFilter());//创建并设置类过滤器
}
public boolean matches(Method method, Class<?> targetClass) {//重写matches方法 方法的过滤器
TransactionAttributeSource tas = getTransactionAttributeSource();//拿到AnnotationTransactionAttributeSource对象
return (tas == null || tas.getTransactionAttribute(method, targetClass) != null);// AnnotationTransactionAttributeSource对象父类AbstractFallbackTransactionAttributeSource有getTransactionAttribute方法
}
private class TransactionAttributeSourceClassFilter implements ClassFilter {//类过滤器
@Override
public boolean matches(Class<?> clazz) {
// TransactionalProxy它是SpringProxy的子类。 如果是被TransactionProxyFactoryBean生产出来的Bean,就会自动实现此接口,那么就不会被这里再次代理了
// PlatformTransactionManager:spring抽象的事务管理器
// PersistenceExceptionTranslator对RuntimeException转换成DataAccessException的转换接口
if (TransactionalProxy.class.isAssignableFrom(clazz) ||
TransactionManager.class.isAssignableFrom(clazz) ||
PersistenceExceptionTranslator.class.isAssignableFrom(clazz)) {
return false;
}
TransactionAttributeSource tas = getTransactionAttributeSource();//getTransactionAttributeSource被重写 直接返回TransactionAttributeSource
return (tas == null || tas.isCandidateClass(clazz));//子类AnnotationTransactionAttributeSource重写
}
}
AnnotationTransactionAttributeSource
1、 创建了annotationParsers对象用来解析事务注解
2、重写了isCandidateClass方法 通过parser解析器来解析类上是否有事务注解 比如@Transactional
3、重写了findTransactionAttribute方法 分别可以查找类和方法上的事务注解
//我们也可以设置ejb和 jta的事务注解 通常还是用的spring的
public AnnotationTransactionAttributeSource(boolean publicMethodsOnly) {
this.publicMethodsOnly = publicMethodsOnly;
if (jta12Present || ejb3Present) {
this.annotationParsers = new LinkedHashSet<>(4);
this.annotationParsers.add(new SpringTransactionAnnotationParser());//创建spring的注解解析器
if (jta12Present) {
this.annotationParsers.add(new JtaTransactionAnnotationParser());
}
if (ejb3Present) {
this.annotationParsers.add(new Ejb3TransactionAnnotationParser());
}
}
else {
this.annotationParsers = Collections.singleton(new SpringTransactionAnnotationParser());//创建spring的注解解析器
}
}
public boolean isCandidateClass(Class<?> targetClass) {
for (TransactionAnnotationParser parser : this.annotationParsers) {
if (parser.isCandidateClass(targetClass)) {//通过parser解析器 来判断是否是候选类 判断类是否有事务注解 比如org.springframework.transaction.annotation.Transactional
return true;
}
}
return false;
}
protected TransactionAttribute findTransactionAttribute(Class<?> clazz) {//查找类上事务的注解
return determineTransactionAttribute(clazz);
}
protected TransactionAttribute findTransactionAttribute(Method method) {//查找方法上事务的注解
return determineTransactionAttribute(method);//确定事务的注解
}
protected TransactionAttribute determineTransactionAttribute(AnnotatedElement element) {
for (TransactionAnnotationParser parser : this.annotationParsers) {//通过annotationParser找到事务注解
TransactionAttribute attr = parser.parseTransactionAnnotation(element);//解析Transactional注解
if (attr != null) {
return attr;
}
}
return null;
}
AnnotationTransactionAttributeSource的父类AbstractFallbackTransactionAttributeSource
重写getTransactionAttribute方法: 拿到事务属性 adivice增强中会用到
1.1、先从实现类的方法上找事务注解
1.2、实现类的方法上没有 就从接口的方法上找
1.3、还没有 就再从实现类上找事务注解 如果还没有就从接口类上找事务注解
public TransactionAttribute getTransactionAttribute(Method method, @Nullable Class<?> targetClass) {//拿到事务属性
if (method.getDeclaringClass() == Object.class) {//是否是Object对象 必须是
return null;
}
// First, see if we have a cached value.
Object cacheKey = getCacheKey(method, targetClass);
TransactionAttribute cached = this.attributeCache.get(cacheKey);
if (cached != null) {
// Value will either be canonical value indicating there is no transaction attribute,
// or an actual transaction attribute.
if (cached == NULL_TRANSACTION_ATTRIBUTE) {
return null;
}
else {
return cached;
}
}
else {//缓存为空
// We need to work it out.
TransactionAttribute txAttr = computeTransactionAttribute(method, targetClass);//拿到transaction注解属性
// Put it in the cache.
if (txAttr == null) {
this.attributeCache.put(cacheKey, NULL_TRANSACTION_ATTRIBUTE);//放入缓存
}
else {
String methodIdentification = ClassUtils.getQualifiedMethodName(method, targetClass);
if (txAttr instanceof DefaultTransactionAttribute) {
((DefaultTransactionAttribute) txAttr).setDescriptor(methodIdentification);
}
if (logger.isTraceEnabled()) {
logger.trace("Adding transactional method '" + methodIdentification + "' with attribute: " + txAttr);
}
this.attributeCache.put(cacheKey, txAttr);
}
return txAttr;
}
}
protected TransactionAttribute computeTransactionAttribute(Method method, @Nullable Class<?> targetClass) {
// Don't allow no-public methods as required. 判断我们的事务方法上的修饰符是不是public的
if (allowPublicMethodsOnly() && !Modifier.isPublic(method.getModifiers())) {
return null;
}
// The method may be on an interface, but we need attributes from the target class.
// If the target class is null, the method will be unchanged. 获取最合适的方法 method可能是接口方法 specificMethod就是实现类的方法
Method specificMethod = AopUtils.getMostSpecificMethod(method, targetClass);
// First try is the method in the target class. 第一步,我们先去目标class的方法上去找我们的事务注解 先去方法上找
TransactionAttribute txAttr = findTransactionAttribute(specificMethod);//通过parser解析器找到相关事务注解 解析注解对应的属性信息
if (txAttr != null) {
return txAttr;
}
// Second try is the transaction attribute on the target class. //第二步:去我们targetClass类的实现类上找事务注解 方法上没有声明 就去类上找
//如果实现类上没有 则会去接口类上找
txAttr = findTransactionAttribute(specificMethod.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
if (specificMethod != method) {
// Fallback is to look at the original method.
txAttr = findTransactionAttribute(method);
if (txAttr != null) {
return txAttr;
}
// Last fallback is the class of the original method.
txAttr = findTransactionAttribute(method.getDeclaringClass());
if (txAttr != null && ClassUtils.isUserLevelMethod(method)) {
return txAttr;
}
}
return null;
}
如何将他们串联起来
我们的InfrastructureAdvisorAutoProxyCreator继承了AbstractAutoProxyCreator 在spring 实例化bean的时候会调用其postProcessAfterInitialization方法
在找到合法的advisor方法findEligibleAdvisors
2.1、找到事务注入的advisor:BeanFactoryTransactionAttributeSourceAdvisor
2.2、事务注入的beanPostProcessor:InfrastructureAdvisorAutoProxyCreator会校验其合法性
2.3、事务注入的pointcut:TransactionAttributeSourcePointcut提前过滤合格的advisor
这样合格的 advisor就给我们找到了
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator#findEligibleAdvisors
protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
//1、findCandidateAdvisors方法在before方法中执行过并缓存起来 aspectj的advisor即InstantiationModelAwarePointcutAdvisorImpl spring事务的即BeanFactoryTransactionAttributeSourceAdvisor
List<Advisor> candidateAdvisors = findCandidateAdvisors();//找到候选的advisor 也就是用户自定义的advisor 并create这个bean
//2、通过pointcut去判断这个advisor是否匹配
List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);//判断是否匹配
extendAdvisors(eligibleAdvisors);//扩展的advisor
if (!eligibleAdvisors.isEmpty()) {
//3、对advisor进行排序
eligibleAdvisors = sortAdvisors(eligibleAdvisors);//对advisor进行排序
}
return eligibleAdvisors;
}
public static List<Advisor> findAdvisorsThatCanApply(List<Advisor> candidateAdvisors, Class<?> clazz) {
if (candidateAdvisors.isEmpty()) {
return candidateAdvisors;
}
List<Advisor> eligibleAdvisors = new ArrayList<>();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor && canApply(candidate, clazz)) {//IntroductionAdvisor的advisor
eligibleAdvisors.add(candidate);
}
}
boolean hasIntroductions = !eligibleAdvisors.isEmpty();
for (Advisor candidate : candidateAdvisors) {
if (candidate instanceof IntroductionAdvisor) {//引入的advisor
// already processed 已经处理过了
continue;
}
if (canApply(candidate, clazz, hasIntroductions)) {//是否可以匹配 以事务为例 就判断类或者方法上是否有@Transactional注解 合格的就加进来
eligibleAdvisors.add(candidate);//合格的就加进来
}
}
return eligibleAdvisors;
}
public static boolean canApply(Advisor advisor, Class<?> targetClass, boolean hasIntroductions) {
if (advisor instanceof IntroductionAdvisor) {//引入类型的advisor
return ((IntroductionAdvisor) advisor).getClassFilter().matches(targetClass);
}
else if (advisor instanceof PointcutAdvisor) {//aop的advisor cglib对应的advisor
PointcutAdvisor pca = (PointcutAdvisor) advisor;
return canApply(pca.getPointcut(), targetClass, hasIntroductions);//是否匹配 通过match去匹配 //事务的AnnotationTransactionAttributeSource 重写了 match方法
}
else {
// It doesn't have a pointcut so we assume it applies.
return true;
}
}
public static boolean canApply(Pointcut pc, Class<?> targetClass, boolean hasIntroductions) {
Assert.notNull(pc, "Pointcut must not be null");
// 1、进行类级别过滤 就是通过pointcut解析类是否符合规范 事务的pointcut重写了该方法
if (!pc.getClassFilter().matches(targetClass)) {
return false;
}
// 2、拿到方法的matcher
MethodMatcher methodMatcher = pc.getMethodMatcher();//TransactionAttributeSourcePointcut
if (methodMatcher == MethodMatcher.TRUE) {
// No need to iterate the methods if we're matching any method anyway...
return true;
}
IntroductionAwareMethodMatcher introductionAwareMethodMatcher = null;
if (methodMatcher instanceof IntroductionAwareMethodMatcher) {
introductionAwareMethodMatcher = (IntroductionAwareMethodMatcher) methodMatcher;
}
Set<Class<?>> classes = new LinkedHashSet<>();
if (!Proxy.isProxyClass(targetClass)) {
classes.add(ClassUtils.getUserClass(targetClass));
}
classes.addAll(ClassUtils.getAllInterfacesForClassAsSet(targetClass));
for (Class<?> clazz : classes) {
Method[] methods = ReflectionUtils.getAllDeclaredMethods(clazz);//找到所有方法
for (Method method : methods) {
//3、进行方法级别过滤
if (introductionAwareMethodMatcher != null ?
introductionAwareMethodMatcher.matches(method, targetClass, hasIntroductions) :
methodMatcher.matches(method, targetClass)) {//进行方法级别过滤 事务的pointcut重写了该方法
return true;
}
}
}
return false;
}
protected List<Advisor> findCandidateAdvisors() {//该方法会被aspectj重写
Assert.state(this.advisorRetrievalHelper != null, "No BeanFactoryAdvisorRetrievalHelper available");
return this.advisorRetrievalHelper.findAdvisorBeans();//找到advisor的bean
}
//找到advisor 然后创建创建bean
public List<Advisor> findAdvisorBeans() {
// Determine list of advisor bean names, if not cached already.
String[] advisorNames = this.cachedAdvisorBeanNames;
if (advisorNames == null) {
// Do not initialize FactoryBeans here: We need to leave all regular beans
// uninitialized to let the auto-proxy creator apply to them! 能拿到事务的advisor BeanFactoryTransactionAttributeSourceAdvisor
advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
this.beanFactory, Advisor.class, true, false);
this.cachedAdvisorBeanNames = advisorNames;
}
if (advisorNames.length == 0) {
return new ArrayList<>();
}
//ioc容器中找到了我们配置的BeanFactoryTransactionAttributeSourceAdvisor
List<Advisor> advisors = new ArrayList<>();
for (String name : advisorNames) {
if (isEligibleBean(name)) {//事务的bpp:InfrastructureAdvisorAutoProxyCreator重写了相关方法
if (this.beanFactory.isCurrentlyInCreation(name)) {//是不是正在创建中的bean
if (logger.isTraceEnabled()) {
logger.trace("Skipping currently created advisor '" + name + "'");
}
}
else {//不是
try {
advisors.add(this.beanFactory.getBean(name, Advisor.class));//getBean 创建bean 添加到advisors中
}
catch (BeanCreationException ex) {
Throwable rootCause = ex.getMostSpecificCause();
if (rootCause instanceof BeanCurrentlyInCreationException) {
BeanCreationException bce = (BeanCreationException) rootCause;
String bceBeanName = bce.getBeanName();
if (bceBeanName != null && this.beanFactory.isCurrentlyInCreation(bceBeanName)) {
if (logger.isTraceEnabled()) {
logger.trace("Skipping advisor '" + name +
"' with dependency on currently created bean: " + ex.getMessage());
}
// Ignore: indicates a reference back to the bean we're trying to advise.
// We want to find advisors other than the currently created bean itself.
continue;
}
}
throw ex;
}
}
}
}
return advisors;
}
再看事务的增强逻辑:TransactionInterceptor
伪代码如下 当然spring实现的比这个更复杂
//1、拿到数据库链接
Connection conn = getConnection
try{
//2、开启事务
conn.setAutoCommit(false);
//3、执行业务逻辑
method.invoke();
}catch{
//4、异常回滚事务
conn.rollBack();
}
//5、正常情况提交事务
conn.commit();
分析其源码:
org.springframework.transaction.interceptor.TransactionInterceptor#invoke
public Object invoke(MethodInvocation invocation) throws Throwable {
// Work out the target class: may be {@code null}.
// The TransactionAttributeSource should be passed the target class
// as well as the method, which may be from an interface.
Class<?> targetClass = (invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null);
// Adapt to TransactionAspectSupport's invokeWithinTransaction...
return invokeWithinTransaction(invocation.getMethod(), targetClass, invocation::proceed);//事务增强逻辑
}
//以非回调事务为例
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
final InvocationCallback invocation) throws Throwable {
// If the transaction attribute is null, the method is non-transactional.
TransactionAttributeSource tas = getTransactionAttributeSource();//拿到AnnotationTransactionAttributeSource 也就是事务注解配置的相关属性源
final TransactionAttribute txAttr = (tas != null ? tas.getTransactionAttribute(method, targetClass) : null);//拿到事务属性 RuleBasedTransactionAttribute
final TransactionManager tm = determineTransactionManager(txAttr);//找到事务管理器 创建事务用
if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager) {//响应式事务管理器
...代码省略...
}
PlatformTransactionManager ptm = asPlatformTransactionManager(tm);//强制类型转换为平台事务管理器
final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);//从txAttr的discriptor中拿到方法名
if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {//非回调事务管理器
// Standard transaction demarcation with getTransaction and commit/rollback calls.
// 1、根据事务的传播级别看情况创建事务 开启事务
TransactionInfo txInfo = createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);
Object retVal;
try {
// This is an around advice: Invoke the next interceptor in the chain.
// This will normally result in a target object being invoked.
retVal = invocation.proceedWithInvocation();//反射执行目标方法
}
catch (Throwable ex) {
// target invocation exception
// 2、异常情况回滚事务
completeTransactionAfterThrowing(txInfo, ex);
throw ex;
}
finally {
//清理一些线程变量
cleanupTransactionInfo(txInfo);
}
if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
// Set rollback-only in case of Vavr failure matching our rollback rules...
TransactionStatus status = txInfo.getTransactionStatus();
if (status != null && txAttr != null) {
retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
}
}
//3、正常情况提交事务
commitTransactionAfterReturning(txInfo);
return retVal;
}
else {//回调事务管理器
...省略代码...
}
}
关键代码:
createTransactionIfNecessary:根据事务的传播级别看情况创建事务
completeTransactionAfterThrowing 异常情况下回滚事务
commitTransactionAfterReturning 正常情况下提交事务
挨个分析:
org.springframework.transaction.interceptor.TransactionAspectSupport#createTransactionIfNecessary
protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm,
@Nullable TransactionAttribute txAttr, final String joinpointIdentification) {
// If no name specified, apply method identification as transaction name.
if (txAttr != null && txAttr.getName() == null) {//创建代理事务属性
txAttr = new DelegatingTransactionAttribute(txAttr) {
@Override
public String getName() {
return joinpointIdentification;
}
};
}
TransactionStatus status = null;
if (txAttr != null) {
if (tm != null) {
//1、拿到事务
status = tm.getTransaction(txAttr);//拿到事务
}
else {
if (logger.isDebugEnabled()) {
logger.debug("Skipping transactional joinpoint [" + joinpointIdentification +
"] because no transaction manager has been configured");
}
}
}
//2、准备事务信息
return prepareTransactionInfo(tm, txAttr, joinpointIdentification, status);//准备事务
}
org.springframework.transaction.support.AbstractPlatformTransactionManager#getTransaction
public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition)
throws TransactionException {
// Use defaults if no transaction definition given.
TransactionDefinition def = (definition != null ? definition : TransactionDefinition.withDefaults());
//1、获取事务 如果该线程之前已经开启过事务则事务信息保存于线程变量中 能判断出来线程之前是否有开启过事务
Object transaction = doGetTransaction();//获取事务 重要属性connectionHolder保存该线程的连接 用来判断是否开启过事务
boolean debugEnabled = logger.isDebugEnabled();
//2、是否存在事务 通过ConnectionHolder 也就是线程变量中存储的事务信息
if (isExistingTransaction(transaction)) {//是否存在事务 connectionHolder不为空
// Existing transaction found -> check propagation behavior to find out how to behave.
//3、处理已经存在的事务
return handleExistingTransaction(def, transaction, debugEnabled);//存在事务了 处理已经存在的事务
}
//4、处理新开启的事务
// Check definition settings for new transaction.
if (def.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {//判断事务是否超时
throw new InvalidTimeoutException("Invalid transaction timeout", def.getTimeout());
}
/**
* 不同事务的传播级别 的不同处理方式
* 1、MANDATORY- 外部不存在事务 抛出异常
* 2、REQUIRED、REQUIRES_NEW、NESTED 外层即开启新事务
*/
//5、不同事务传播级别下分别处理
// No existing transaction found -> check propagation behavior to find out how to proceed.
if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
throw new IllegalTransactionStateException(
"No existing transaction found for transaction marked with propagation 'mandatory'");
}
else if (def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
def.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
SuspendedResourcesHolder suspendedResources = suspend(null);//挂起一个为null的事务
if (debugEnabled) {
logger.debug("Creating new transaction with name [" + def.getName() + "]: " + def);
}
try {
//6、开启新事务
return startTransaction(def, transaction, debugEnabled, suspendedResources);//开启事务
}
catch (RuntimeException | Error ex) {
resume(null, suspendedResources);
throw ex;
}
}
//7、不开启事务的情况
else {
// Create "empty" transaction: no actual transaction, but potentially synchronization.
if (def.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
logger.warn("Custom isolation level specified but no actual transaction initiated; " +
"isolation level will effectively be ignored: " + def);
}
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
return prepareTransactionStatus(def, null, true, newSynchronization, debugEnabled, null);
}
}
protected Object doGetTransaction() {//数据源事务管理器创建
DataSourceTransactionObject txObject = new DataSourceTransactionObject();//创建事务
txObject.setSavepointAllowed(isNestedTransactionAllowed());
ConnectionHolder conHolder =
(ConnectionHolder) TransactionSynchronizationManager.getResource(obtainDataSource());//从事务同步管理器中 通过key-datasource数据源 来获取 第一次进来肯定没有 存在threadlocal修饰的全局变量resources中
txObject.setConnectionHolder(conHolder, false);//设置connectionHolder 重要属性保存 外层设置的newConnectionHolder永远为false
return txObject;
}
private TransactionStatus handleExistingTransaction(//处理已经存在的事务
TransactionDefinition definition, Object transaction, boolean debugEnabled)
throws TransactionException {
//1、PROPAGATION_NEVER传播级别 内层事务会抛出异常
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NEVER) {//never级别 抛出异常
throw new IllegalTransactionStateException(
"Existing transaction found for transaction marked with propagation 'never'");
}
//2、NOT_SUPPORTED级别 挂起外层事务 不开启新事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NOT_SUPPORTED) {//NOT_SUPPORTED级别
if (debugEnabled) {
logger.debug("Suspending current transaction");
}
Object suspendedResources = suspend(transaction);//挂起 清空transaction中的connectionHolder和 线程变量resource中暂存变量
boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);//true 新同步器
return prepareTransactionStatus(//事务清空 newTransaction为false
definition, null, false, newSynchronization, debugEnabled, suspendedResources);
}
//3、PROPAGATION_REQUIRES_NEW级别 挂起外层事务 开启新事务
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW) {
if (debugEnabled) {
logger.debug("Suspending current transaction, creating new transaction with name [" +
definition.getName() + "]");
}
SuspendedResourcesHolder suspendedResources = suspend(transaction);//挂起事务
try {
//开启新事务
return startTransaction(definition, transaction, debugEnabled, suspendedResources);
}
catch (RuntimeException | Error beginEx) {
resumeAfterBeginException(transaction, suspendedResources, beginEx);
throw beginEx;
}
}
//4、PROPAGATION_NESTED
if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
if (!isNestedTransactionAllowed()) {
throw new NestedTransactionNotSupportedException(
"Transaction manager does not allow nested transactions by default - " +
"specify 'nestedTransactionAllowed' property with value 'true'");
}
if (debugEnabled) {
logger.debug("Creating nested transaction with name [" + definition.getName() + "]");
}
//4.1、如果使用了回滚点默认为true 使用外部事务 创建回滚点
if (useSavepointForNestedTransaction()) {
// Create savepoint within existing Spring-managed transaction,
// through the SavepointManager API implemented by TransactionStatus.
// Usually uses JDBC 3.0 savepoints. Never activates Spring synchronization.
DefaultTransactionStatus status =
prepareTransactionStatus(definition, transaction, false, false, debugEnabled, null);
status.createAndHoldSavepoint();
return status;
}
//4.2、否则开启新事务 外部事务使用内部事务
else {
// Nested transaction through nested begin and commit/rollback calls.
// Usually only for JTA: Spring synchronization might get activated here
// in case of a pre-existing JTA transaction.
return startTransaction(definition, transaction, debugEnabled, null);
}
}
// Assumably PROPAGATION_SUPPORTS or PROPAGATION_REQUIRED.
if (debugEnabled) {
logger.debug("Participating in existing transaction");
}
if (isValidateExistingTransaction()) {//默认false
if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT) {
Integer currentIsolationLevel = TransactionSynchronizationManager.getCurrentTransactionIsolationLevel();
if (currentIsolationLevel == null || currentIsolationLevel != definition.getIsolationLevel()) {
Constants isoConstants = DefaultTransactionDefinition.constants;
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] specifies isolation level which is incompatible with existing transaction: " +
(currentIsolationLevel != null ?
isoConstants.toCode(currentIsolationLevel, DefaultTransactionDefinition.PREFIX_ISOLATION) :
"(unknown)"));
}
}
if (!definition.isReadOnly()) {
if (TransactionSynchronizationManager.isCurrentTransactionReadOnly()) {
throw new IllegalTransactionStateException("Participating transaction with definition [" +
definition + "] is not marked as read-only but existing transaction is");
}
}
}
//5、其他情况融合到外部事务
boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
return prepareTransactionStatus(definition, transaction, false, newSynchronization, debugEnabled, null);
}
回滚事务:
protected void completeTransactionAfterThrowing(@Nullable TransactionInfo txInfo, Throwable ex) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() +
"] after exception: " + ex);
}
//1、rollbackOn 根据异常类型判断是否要回滚事务
if (txInfo.transactionAttribute != null && txInfo.transactionAttribute.rollbackOn(ex)) {
try {
//2、符合异常类型的回滚事务
txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by rollback exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by rollback exception", ex);
throw ex2;
}
}
//3、不符合异常类型的 提交事务
else {
// We don't roll back on this exception.
// Will still roll back if TransactionStatus.isRollbackOnly() is true.
try {
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
catch (TransactionSystemException ex2) {
logger.error("Application exception overridden by commit exception", ex);
ex2.initApplicationException(ex);
throw ex2;
}
catch (RuntimeException | Error ex2) {
logger.error("Application exception overridden by commit exception", ex);
throw ex2;
}
}
}
}
public boolean rollbackOn(Throwable ex) {
if (logger.isTraceEnabled()) {
logger.trace("Applying rules to determine whether transaction should rollback on " + ex);
}
RollbackRuleAttribute winner = null;
int deepest = Integer.MAX_VALUE;
if (this.rollbackRules != null) {
//遍历rollback类型
for (RollbackRuleAttribute rule : this.rollbackRules) {
//看异常名是否匹配 不匹配就往异常父类找 依次往上找 最大深度Integer.MAX_VALUE
int depth = rule.getDepth(ex);
if (depth >= 0 && depth < deepest) {
deepest = depth;
winner = rule;
}
}
}
if (logger.isTraceEnabled()) {
logger.trace("Winning rollback rule is: " + winner);
}
// User superclass behavior (rollback on unchecked) if no rule matches.
if (winner == null) {
logger.trace("No relevant rollback rule found: applying default rules");
return super.rollbackOn(ex);
}
return !(winner instanceof NoRollbackRuleAttribute);
}
提交事务:
protected void commitTransactionAfterReturning(@Nullable TransactionInfo txInfo) {
if (txInfo != null && txInfo.getTransactionStatus() != null) {
if (logger.isTraceEnabled()) {
logger.trace("Completing transaction for [" + txInfo.getJoinpointIdentification() + "]");
}
//提交事务
txInfo.getTransactionManager().commit(txInfo.getTransactionStatus());
}
}
事务传播级别详述:
事务传播行为类型 | 外部不存在事务 | 外部存在事务 | 使用方式 |
REQUIRED(默认) | 开启新的事务 | 融合到外部事务中 | @Transactional(propagation = Propagation.REQUIRED) 适用增删改查 |
SUPPORTS | 不开启新的事务 | 融合到外部事务中 | @Transactional(propagation = Propagation.SUPPORTS) 适用查询 |
REQUIRES_NEW | 开启新的事务 | 不用外部事务,创建新的事务 | @Transactional(propagation = Propagation.REQUIRES_NEW) 适用内部事务和外部事务不存在业务关联情况,如日志 |
NOT_SUPPORTED | 不开启新的事务 | 不用外部事务 | @Transactional(propagation = Propagation.NOT_SUPPORTED) 不常用 |
NEVER | 不开启新的事务 | 抛出异常 | @Transactional(propagation = Propagation.NEVER ) 不常用 |
MANDATORY | 抛出异常 | 融合到外部事务中 | @Transactional(propagation = Propagation.MANDATORY) 不常用 |
NESTED | 开启新的事务 | 融合到外部事务中,SavePoint机制 | @Transactional(propagation = Propagation.NESTED) 不常用 |
关于几个隔离级别的特殊情况
场景1、
外层开启事务(REQUIRED)
内层事务是REQUIRES_NEW 会挂起外层事务 开启内层新事务
1.1、如果内层报错 不try catch内层 内层事务回滚 外层事务回滚
1.2、如果内层报错 且 try catch内层 内层事务回滚 外层事务提交
1.3、如果内层不报错 外层报错 内层事务提交 外层事务回滚
public class TransServiceImpl implements ITransService{
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
ITransService transServiceImpl1;
@Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
@Override
public void insert() {
jdbcTemplate.execute("insert into test(column1) values('aaaa')");
transServiceImpl1.insert();
int i =5/0;//异常 sql回滚
}
}
@Service
public class TransServiceImpl1 implements ITransService{
@Autowired
JdbcTemplate jdbcTemplate;
@Override
@Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRES_NEW)
public void insert() {
jdbcTemplate.execute("insert into test(column1) values('bbbb')");
// int i =5/0;//异常 sql回滚
}
}
场景2、
外层开启事务(REQUIRED)
内层事务是NESTED 融合外部事务
1、内层报错且没有try catch 内层回滚 外层回滚
2、内层报错且try catch 内层回滚 外层提交
3、内层不报错 外层报错 内层回滚 外层回滚
@Service
public class TransServiceImpl implements ITransService{
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
ITransService transServiceImpl1;
@Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
@Override
public void insert1() {
jdbcTemplate.execute("insert into test(column1) values('aaaa')");
transServiceImpl1.insert1();
int i =5/0;//异常 sql回滚
}
}
@Service
public class TransServiceImpl1 implements ITransService{
@Autowired
JdbcTemplate jdbcTemplate;
@Override
@Transactional(rollbackFor=Exception.class,propagation = Propagation.NESTED)
public void insert1() {
jdbcTemplate.execute("insert into test(column1) values('bbbb')");
// int i =5/0;//异常 sql回滚
}
}
场景3、
外层开启事务(REQUIRED)
内层事务是REQUIRED 融合外部事务
1、内层报错且没有try catch 内层回滚 外层回滚
2、内层报错且try catch 内层回滚 外层回滚并报错:
![](https://i-blog.csdnimg.cn/blog_migrate/3d54ec487ce6f0145b33e4f3f6336f16.png)
3、内层不报错 外层报错 内层回滚 外层回滚
@Service
public class TransServiceImpl implements ITransService{
@Autowired
JdbcTemplate jdbcTemplate;
@Autowired
ITransService transServiceImpl1;
@Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
@Override
public void insert2() {
jdbcTemplate.execute("insert into test(column1) values('aaaa')");
try {
transServiceImpl1.insert2();
} catch (Exception e) {
}
// int i =5/0;//异常 sql回滚
}
}
@Service
public class TransServiceImpl1 implements ITransService{
@Autowired
JdbcTemplate jdbcTemplate;
@Override
@Transactional(rollbackFor=Exception.class,propagation = Propagation.REQUIRED)
public void insert2() {
jdbcTemplate.execute("insert into test(column1) values('bbbb')");
int i =5/0;//异常 sql回滚
}
}
事务的源码很复杂 本文仅分析了主干信息 并未分析细枝末节信息 但这些信息有些也很重要。