【原创】002 | 搭上SpringBoot事务源码分析专车
前言
如果这是你第二次看到师长,说明你在觊觎我的美色!
点赞+关注再看,养成习惯
没别的意思,就是需要你的窥屏^_^
专车介绍**
该趟专车是开往spring boot事务源码分析的专车
专车问题
- 为什么加上@transactional注解就可以实现事务?
- 分析事务源码之后我们可以学到什么?
专车名词
事务
程序中通常使用事务来达到数据的一致性,从而避免脏数据
编程式事务
在业务方法开头开启事务,然后对我们的业务进行try-catch,假设没有异常则提交事务,如果出现异常,则在catch模块回滚事务
声明式事务由来
如果采用编程式事务,那么在任何需要事务的地方都要开启事务、try-catch、提交或者回滚事务,会导致重复编码、编写与业务无关的代码。基于spring aop思想,我们可以利用aop的方式,对需要使用事务的方法进行增强,将公用的部分提取出来,那么就实现了声明式事务。
spring提供的声明式事务
在需要使用事务的业务方法上添加@transactional注解,那么就可以使用事务的特性,要么成功,要么失败
spring aop核心概念
- 切面:切面是由切点和通知组成
- 切点:用来匹配符合条件类或方法
- 通知:需要执行的操作
专车分析
基于spring boot自动配置原理,我们应该寻找xxxautoconfiguration自动配置类,此处要寻找和事务相关的,那么自然是transactionautoconfiguration
自动配置
打开transactionautoconfiguration自动配置类
@configuration @conditionalonbean(platformtransactionmanager.class) @conditionalonmissingbean(abstracttransactionmanagementconfiguration.class) public static class enabletransactionmanagementconfiguration { @configuration @enabletransactionmanagement(proxytargetclass = false) @conditionalonproperty(prefix = "spring.aop", name = "proxy-target-class", havingvalue = "false", matchifmissing = false) public static class jdkdynamicautoproxyconfiguration { } @configuration @enabletransactionmanagement(proxytargetclass = true) @conditionalonproperty(prefix = "spring.aop", name = "proxy-target-class", havingvalue = "true", matchifmissing = true) public static class cglibautoproxyconfiguration { } }
可以看到开启事务管理器的注解@enabletransactionmanagement
@target(elementtype.type) @retention(retentionpolicy.runtime) @documented @import(transactionmanagementconfigurationselector.class) public @interface enabletransactionmanagement {}
查看transactionmanagementconfigurationselector导入的类
protected string[] selectimports(advicemode advicemode) { switch (advicemode) { case proxy: return new string[] {autoproxyregistrar.class.getname(), proxytransactionmanagementconfiguration.class.getname()}; case aspectj: return new string[] {determinetransactionaspectclass()}; default: return null; } }
可以看到导入了autoproxyregistrar和proxytransactionmanagementconfiguration
首先看看autoproxyregistrar,该类实现了importbeandefinitionregistrar
public void registerbeandefinitions(annotationmetadata importingclassmetadata, beandefinitionregistry registry) { boolean candidatefound = false; set<string> annotypes = importingclassmetadata.getannotationtypes(); for (string annotype : annotypes) { annotationattributes candidate = annotationconfigutils.attributesfor(importingclassmetadata, annotype); if (candidate == null) { continue; } object mode = candidate.get("mode"); object proxytargetclass = candidate.get("proxytargetclass"); if (mode != null && proxytargetclass != null && advicemode.class == mode.getclass() && boolean.class == proxytargetclass.getclass()) { candidatefound = true; if (mode == advicemode.proxy) { // 注册自动代理创建器 aopconfigutils.registerautoproxycreatorifnecessary(registry); if ((boolean) proxytargetclass) { aopconfigutils.forceautoproxycreatortouseclassproxying(registry); return; } } } } }
注册自动代理创建器,aopconfigutils#registerautoproxycreatorifnecessary
public static beandefinition registerautoproxycreatorifnecessary( beandefinitionregistry registry, @nullable object source) { // 注册了infrastructureadvisorautoproxycreator到ioc容器中 return registerorescalateapcasrequired(infrastructureadvisorautoproxycreator.class, registry, source); }
infrastructureadvisorautoproxycreator是abstractautoproxycreator的子类,abstractautoproxycreator又实现了beanpostprocessor接口,那么在bean初始化完毕后就会调用postprocessafterinstantiation()方法,postprocessafterinstantiation()定义在abstractautoproxycreator类中
beanpostprocessor后置处理
打开abstractautoproxycreator
@override public object postprocessafterinitialization(@nullable object bean, string beanname) { if (bean != null) { object cachekey = getcachekey(bean.getclass(), beanname); if (!this.earlyproxyreferences.contains(cachekey)) { // 如果满足条件对bean进行包裹 return wrapifnecessary(bean, beanname, cachekey); } } return bean; }
该方法调用了wrapifnecessary()方法
protected object wrapifnecessary(object bean, string beanname, object cachekey) { // create proxy if we have advice. // 获取bean的切面和通知 object[] specificinterceptors = getadvicesandadvisorsforbean(bean.getclass(), beanname, null); // 需要代理 if (specificinterceptors != do_not_proxy) { this.advisedbeans.put(cachekey, boolean.true); // 创建代理 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; }
根据注释的意思就是如果存在advice,那么就创建代理,
寻找切面
进入abstractadvisorautoproxycreator#getadvicesandadvisorsforbean
protected object[] getadvicesandadvisorsforbean( class<?> beanclass, string beanname, @nullable targetsource targetsource) { // 查找符合条件的切面 list<advisor> advisors = findeligibleadvisors(beanclass, beanname); // 不存在符合条件的切面,则不生成代理 if (advisors.isempty()) { return do_not_proxy; } return advisors.toarray(); }
该代码第一句最重要,如果不存在符合条件的切面,那么最终的结果返回null,根据上面分析的,如果为null就不创建代理,否则创建代理。接下来看看第一句的实现
protected list<advisor> findeligibleadvisors(class<?> beanclass, string beanname) { // 获取所有候选的切面,也就是类型为advisor的切面,此处获取到的候选切面为beanfactorytransactionattributesourceadvisor list<advisor> candidateadvisors = findcandidateadvisors(); // 从候选的切面中获取可以解析当前bean的切面,最终符合条件的切面为beanfactorytransactionattributesourceadvisor list<advisor> eligibleadvisors = findadvisorsthatcanapply(candidateadvisors, beanclass, beanname); extendadvisors(eligibleadvisors); if (!eligibleadvisors.isempty()) { eligibleadvisors = sortadvisors(eligibleadvisors); } return eligibleadvisors; }
为什么上面获取到的切面是beanfactorytransactionattributesourceadvisor?是否还记得之前导入配置类的时候还有一个配置类没有分析?那就是proxytransactionmanagementconfiguration
打开proxytransactionmanagementconfiguration
@configuration public class proxytransactionmanagementconfiguration extends abstracttransactionmanagementconfiguration { // 创建beanfactorytransactionattributesourceadvisor @bean(name = transactionmanagementconfigutils.transaction_advisor_bean_name) @role(beandefinition.role_infrastructure) public beanfactorytransactionattributesourceadvisor transactionadvisor() { beanfactorytransactionattributesourceadvisor advisor = new beanfactorytransactionattributesourceadvisor(); advisor.settransactionattributesource(transactionattributesource()); // 设置切面对应的通知,后面分析会用到 advisor.setadvice(transactioninterceptor()); if (this.enabletx != null) { advisor.setorder(this.enabletx.<integer>getnumber("order")); } return advisor; } @bean @role(beandefinition.role_infrastructure) public transactionattributesource transactionattributesource() { return new annotationtransactionattributesource(); } // 创建通知 @bean @role(beandefinition.role_infrastructure) public transactioninterceptor transactioninterceptor() { transactioninterceptor interceptor = new transactioninterceptor(); interceptor.settransactionattributesource(transactionattributesource()); if (this.txmanager != null) { interceptor.settransactionmanager(this.txmanager); } return interceptor; } }
通过上面的自动配置,可得知获取到的候选切面为什么是beanfactorytransactionattributesourceadvisor
接下来看看如何从候选切面中找到可以解析当前bean的切面?
protected list<advisor> findadvisorsthatcanapply( list<advisor> candidateadvisors, class<?> beanclass, string beanname) { proxycreationcontext.setcurrentproxiedbeanname(beanname); try { // 查找可以解析当前bean对应的切面 return aoputils.findadvisorsthatcanapply(candidateadvisors, beanclass); } finally { proxycreationcontext.setcurrentproxiedbeanname(null); } }
查找可以解析当前bean对应的切面,aoputils#findadvisorsthatcanapply
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)) { eligibleadvisors.add(candidate); } } boolean hasintroductions = !eligibleadvisors.isempty(); for (advisor candidate : candidateadvisors) { if (candidate instanceof introductionadvisor) { // already processed continue; } // 当前切面是否可以解析bean if (canapply(candidate, clazz, hasintroductions)) { eligibleadvisors.add(candidate); } } return eligibleadvisors; }
候选切面是否可以解析bean
public static boolean canapply(advisor advisor, class<?> targetclass, boolean hasintroductions) { if (advisor instanceof introductionadvisor) { return ((introductionadvisor) advisor).getclassfilter().matches(targetclass); } else if (advisor instanceof pointcutadvisor) { // 由上面分析知道最终的候选切面为beanfactorytransactionattributesourceadvisor // 该类实现了pointcutadvisor pointcutadvisor pca = (pointcutadvisor) advisor; return canapply(pca.getpointcut(), targetclass, hasintroductions); } else { // it doesn't have a pointcut so we assume it applies. return true; } }
候选切面是否可以解析bean
public static boolean canapply(pointcut pc, class<?> targetclass, boolean hasintroductions) { assert.notnull(pc, "pointcut must not be null"); if (!pc.getclassfilter().matches(targetclass)) { return false; } // 获取切面切点方法匹配对象,用来匹配方法是否符合 methodmatcher methodmatcher = pc.getmethodmatcher(); 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对象 method[] methods = reflectionutils.getalldeclaredmethods(clazz); for (method method : methods) { if (introductionawaremethodmatcher != null ? introductionawaremethodmatcher.matches(method, targetclass, hasintroductions) : // 匹配方法是否符合 methodmatcher.matches(method, targetclass)) { return true; } } } return false; }
匹配方法transactionattributesourcepointcut#matches
public boolean matches(method method, class<?> targetclass) { if (transactionalproxy.class.isassignablefrom(targetclass) || platformtransactionmanager.class.isassignablefrom(targetclass) || persistenceexceptiontranslator.class.isassignablefrom(targetclass)) { return false; } transactionattributesource tas = gettransactionattributesource(); // 如果事务属性源对象为空或者事务属性对象不为null返回true,代表匹配成功;否则返回false,匹配失败 return (tas == null || tas.gettransactionattribute(method, targetclass) != null); }
获取事务属性对象,abstractfallbacktransactionattributesource#gettransactionattribute
public transactionattribute gettransactionattribute(method method, @nullable class<?> targetclass) { if (method.getdeclaringclass() == object.class) { 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 { // 计算事务属性对象 transactionattribute txattr = computetransactionattribute(method, targetclass); // 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. 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 = aoputils.getmostspecificmethod(method, targetclass); // first try is the method in the target class. // 首先根据method对象获取事务属性对象 transactionattribute txattr = findtransactionattribute(specificmethod); if (txattr != null) { return txattr; } // second try is the transaction attribute on the target class. // 如果根据method对象获取不到事务属性对象,那么根据class来获取属性对象 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; }
获取属性对象annotationtransactionattributesource#findtransactionattribute
protected transactionattribute findtransactionattribute(class<?> clazz) { return determinetransactionattribute(clazz); }
决定事务属性对象
protected transactionattribute determinetransactionattribute(annotatedelement element) { for (transactionannotationparser annotationparser : this.annotationparsers) { transactionattribute attr = annotationparser.parsetransactionannotation(element); if (attr != null) { return attr; } } return null; }
解析事务属性对象,springtransactionannotationparser#parsetransactionannotation
public transactionattribute parsetransactionannotation(annotatedelement element) { // 判断元素是否含有@transactional注解,通过前面的分析我们可以得出如下结论: // 1、首选判断类的方法上是否含有@transactional注解,如果有就解析 // 2、如果所有的方法都不含有@transactional注解,那么判断当前类是否含有@transactional注解,如果有就解析 // 3、如果类或者类的某个方法含有@transactional注解,那么事务属性对象就不为空,则说明次切面可以解析当前bean annotationattributes attributes = annotatedelementutils.findmergedannotationattributes( element, transactional.class, false, false); if (attributes != null) { return parsetransactionannotation(attributes); } else { return null; } }
回到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; } if (isinfrastructureclass(bean.getclass()) || shouldskip(bean.getclass(), beanname)) { this.advisedbeans.put(cachekey, boolean.false); return bean; } // create proxy if we have advice. // 此处有值返回,进行代理,否则不进行代理 object[] specificinterceptors = getadvicesandadvisorsforbean(bean.getclass(), beanname, null); // 需要进行代理 if (specificinterceptors != do_not_proxy) { this.advisedbeans.put(cachekey, boolean.true); // 创建代理 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; }
创建代理
创建代理abstractautoproxycreator#createproxy
protected object createproxy(class<?> beanclass, @nullable string beanname, @nullable object[] specificinterceptors, targetsource targetsource) { if (this.beanfactory instanceof configurablelistablebeanfactory) { autoproxyutils.exposetargetclass((configurablelistablebeanfactory) this.beanfactory, beanname, beanclass); } // 创建代理工厂 proxyfactory proxyfactory = new proxyfactory(); proxyfactory.copyfrom(this); if (!proxyfactory.isproxytargetclass()) { if (shouldproxytargetclass(beanclass, beanname)) { proxyfactory.setproxytargetclass(true); } else { evaluateproxyinterfaces(beanclass, proxyfactory); } } // 构建切面,此处的切面为beanfactorytransactionattributesourceadvisor advisor[] advisors = buildadvisors(beanname, specificinterceptors); // 设置切面 proxyfactory.addadvisors(advisors); proxyfactory.settargetsource(targetsource); customizeproxyfactory(proxyfactory); proxyfactory.setfrozen(this.freezeproxy); if (advisorsprefiltered()) { proxyfactory.setprefiltered(true); } return proxyfactory.getproxy(getproxyclassloader()); }
获取代理proxyfactory#getproxy
public object getproxy(@nullable classloader classloader) { return createaopproxy().getproxy(classloader); }
创建aop代理
protected final synchronized aopproxy createaopproxy() { if (!this.active) { activate(); } // 此处的this实际上就是proxyfactory return getaopproxyfactory().createaopproxy(this); }
aop代理工厂创建aop代理defaultaopproxyfactory#createaopproxy
public aopproxy createaopproxy(advisedsupport config) throws aopconfigexception { if (config.isoptimize() || config.isproxytargetclass() || hasnousersuppliedproxyinterfaces(config)) { class<?> targetclass = config.gettargetclass(); if (targetclass == null) { throw new aopconfigexception("targetsource cannot determine target class: " + "either an interface or a target is required for proxy creation."); } if (targetclass.isinterface() || proxy.isproxyclass(targetclass)) { return new jdkdynamicaopproxy(config); } // 创建cglib aop代理 return new objenesiscglibaopproxy(config); } else { return new jdkdynamicaopproxy(config); } }
实例化objenesiscglibaopproxy对象
public objenesiscglibaopproxy(advisedsupport config) { super(config); }
父类实例化
public cglibaopproxy(advisedsupport config) throws aopconfigexception { assert.notnull(config, "advisedsupport must not be null"); if (config.getadvisors().length == 0 && config.gettargetsource() == advisedsupport.empty_target_source) { throw new aopconfigexception("no advisors and no targetsource specified"); } // 此处的config就是之前的proxyfactory this.advised = config; this.adviseddispatcher = new adviseddispatcher(this.advised); }
回到之前获取代理的地方
public object getproxy(@nullable classloader classloader) { return createaopproxy().getproxy(classloader); }
通过上面的分析可以得知createaopproxy()返回的是cglibaopproxy
通过cglibaopproxy获取代理,cglibaopproxy#getproxy
public object getproxy(@nullable classloader classloader) { if (logger.istraceenabled()) { logger.trace("creating cglib proxy: " + this.advised.gettargetsource()); } try { class<?> rootclass = this.advised.gettargetclass(); assert.state(rootclass != null, "target class must be available for creating a cglib proxy"); class<?> proxysuperclass = rootclass; if (classutils.iscglibproxyclass(rootclass)) { proxysuperclass = rootclass.getsuperclass(); class<?>[] additionalinterfaces = rootclass.getinterfaces(); for (class<?> additionalinterface : additionalinterfaces) { this.advised.addinterface(additionalinterface); } } // validate the class, writing log messages as necessary. validateclassifnecessary(proxysuperclass, classloader); // configure cglib enhancer... // 创建enhancer对象 enhancer enhancer = createenhancer(); if (classloader != null) { enhancer.setclassloader(classloader); if (classloader instanceof smartclassloader && ((smartclassloader) classloader).isclassreloadable(proxysuperclass)) { enhancer.setusecache(false); } } // 设置父类 enhancer.setsuperclass(proxysuperclass); // 设置接口 enhancer.setinterfaces(aopproxyutils.completeproxiedinterfaces(this.advised)); enhancer.setnamingpolicy(springnamingpolicy.instance); enhancer.setstrategy(new classloaderawareundeclaredthrowablestrategy(classloader)); // 获取回调,重点分析 callback[] callbacks = getcallbacks(rootclass); class<?>[] types = new class<?>[callbacks.length]; for (int x = 0; x < types.length; x++) { types[x] = callbacks[x].getclass(); } // fixedinterceptormap only populated at this point, after getcallbacks call above enhancer.setcallbackfilter(new proxycallbackfilter( this.advised.getconfigurationonlycopy(), this.fixedinterceptormap, this.fixedinterceptoroffset)); // 设置回调类型 enhancer.setcallbacktypes(types); // generate the proxy class and create a proxy instance. // 生成代理并创建代理实例 return createproxyclassandinstance(enhancer, callbacks); } catch (codegenerationexception | illegalargumentexception ex) { throw new aopconfigexception("could not generate cglib subclass of " + this.advised.gettargetclass() + ": common causes of this problem include using a final class or a non-visible class", ex); } catch (throwable ex) { // targetsource.gettarget() failed throw new aopconfigexception("unexpected aop exception", ex); } }
获取回调
private callback[] getcallbacks(class<?> rootclass) throws exception { // parameters used for optimization choices... boolean exposeproxy = this.advised.isexposeproxy(); boolean isfrozen = this.advised.isfrozen(); boolean isstatic = this.advised.gettargetsource().isstatic(); // choose an "aop" interceptor (used for aop calls). // 实例化回调,在调用目标对象方法的时候执行 callback aopinterceptor = new dynamicadvisedinterceptor(this.advised); return callbacks; }
实例化回调部分
private static class dynamicadvisedinterceptor implements methodinterceptor, serializable { private final advisedsupport advised; public dynamicadvisedinterceptor(advisedsupport advised) { // 设置切面信息,也就是之前的proxyfactory this.advised = advised; } @override @nullable // 调用目标方法的时候执行 public object intercept(object proxy, method method, object[] args, methodproxy methodproxy) throws throwable { object oldproxy = null; boolean setproxycontext = false; object target = null; targetsource targetsource = this.advised.gettargetsource(); try { 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); // 获取通知,此处的通知为transactioninterceptor list<object> chain = this.advised.getinterceptorsanddynamicinterceptionadvice(method, targetclass); object retval; // check whether we only have one invokerinterceptor: that is, // no real advice, but just reflective invocation of the target. if (chain.isempty() && modifier.ispublic(method.getmodifiers())) { // 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 = methodproxy.invoke(target, argstouse); } else { // we need to create a method invocation... retval = new cglibmethodinvocation(proxy, target, method, args, targetclass, chain, methodproxy).proceed(); } retval = processreturntype(proxy, target, method, retval); return retval; } finally { if (target != null && !targetsource.isstatic()) { targetsource.releasetarget(target); } if (setproxycontext) { // restore old proxy. aopcontext.setcurrentproxy(oldproxy); } } } @override public boolean equals(object other) { return (this == other || (other instanceof dynamicadvisedinterceptor && this.advised.equals(((dynamicadvisedinterceptor) other).advised))); } /** * cglib uses this to drive proxy creation. */ @override public int hashcode() { return this.advised.hashcode(); } }
调用invocation的处理方法,reflectivemethodinvocation#proceed
public object proceed() throws throwable { // we start with an index of -1 and increment early. if (this.currentinterceptorindex == this.interceptorsanddynamicmethodmatchers.size() - 1) { return invokejoinpoint(); } // 此处的通知transactioninterceptor object interceptororinterceptionadvice = this.interceptorsanddynamicmethodmatchers.get(++this.currentinterceptorindex); 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); } 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. // 调用transactioninterceptor#invoke return ((methodinterceptor) interceptororinterceptionadvice).invoke(this); } }
调用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(); final transactionattribute txattr = (tas != null ? tas.gettransactionattribute(method, targetclass) : null); final platformtransactionmanager tm = determinetransactionmanager(txattr); final string joinpointidentification = methodidentification(method, targetclass, txattr); if (txattr == null || !(tm instanceof callbackpreferringplatformtransactionmanager)) { // standard transaction demarcation with gettransaction and commit/rollback calls. // 创建事务信息对象 transactioninfo txinfo = createtransactionifnecessary(tm, txattr, joinpointidentification); object retval = null; 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 // 业务方法执行异常,进行事务回滚 completetransactionafterthrowing(txinfo, ex); throw ex; } finally { // 清除事务信息对象 cleanuptransactioninfo(txinfo); } // 提交事务 committransactionafterreturning(txinfo); return retval; } else { final throwableholder throwableholder = new throwableholder(); // it's a callbackpreferringplatformtransactionmanager: pass a transactioncallback in. try { object result = ((callbackpreferringplatformtransactionmanager) tm).execute(txattr, status -> { transactioninfo txinfo = preparetransactioninfo(tm, txattr, joinpointidentification, status); try { return invocation.proceedwithinvocation(); } catch (throwable ex) { if (txattr.rollbackon(ex)) { // a runtimeexception: will lead to a rollback. if (ex instanceof runtimeexception) { throw (runtimeexception) ex; } else { throw new throwableholderexception(ex); } } else { // a normal return value: will lead to a commit. throwableholder.throwable = ex; return null; } } finally { cleanuptransactioninfo(txinfo); } }); // check result state: it might indicate a throwable to rethrow. if (throwableholder.throwable != null) { throw throwableholder.throwable; } return result; } catch (throwableholderexception ex) { throw ex.getcause(); } catch (transactionsystemexception ex2) { if (throwableholder.throwable != null) { logger.error("application exception overridden by commit exception", throwableholder.throwable); ex2.initapplicationexception(throwableholder.throwable); } throw ex2; } catch (throwable ex2) { if (throwableholder.throwable != null) { logger.error("application exception overridden by commit exception", throwableholder.throwable); } throw ex2; } } }
到此事务的源码分析就结束了
专车总结
- 导入autoproxyregistrar、proxytransactionmanagementconfiguration配置类
- autoproxyregistrar用来注册infrastructureadvisorautoproxycreator到ioc中,infrastructureadvisorautoproxycreator实现了beanpostprocessor
- 执行beanpostprocessor的后置处理
- 获取由proxytransactionmanagementconfiguration配置类创建的切面
- 通过切面解析bean是否需要创建代理,需要就创建代理
- 执行代理的回调,在回调中拿到通知
- 执行通知,通知里面逻辑:开启事务、执行目标方法、提交或回滚事务
专车回顾
回顾下开头的两个问题:
- 为什么加上@transactional注解就可以实现事务?
- 分析事务源码之后我们可以学到什么?
通过以上分析,第一个问题应该就迎刃而解了,那么通过以上学到的知识我们可以实现什么功能呢?在下一篇我们会在此基础上进行实战,通过@systemlog注解实现系统日志功能。感谢各位撸友乘坐此趟专车,欢迎下次继续乘坐
最后
师长,【java进阶架构师】号主,短短一年在各大平台斩获15w+程序员关注,专注分享java进阶、架构技术、高并发、微服务、bat面试、redis专题、jvm调优、springboot源码、mysql优化等20大进阶架构专题,关注【java进阶架构师】回复【架构】领取2019架构师完整视频一套。
转载说明:请务必注明来源(本文首发于公众号:【java进阶架构师】)