当前位置: 首页 > wzjs >正文

自学做网站2023第三波疫情已经到来了

自学做网站,2023第三波疫情已经到来了,提取wordpress小工具,网站建设宣传广告文章目录 【README】【步骤1】UserAppService调用userSupport.saveNewUser()【步骤2】获取到TransactionInterceptor【步骤3】chain不为空,接着执行CglibMethodInvocation#proceed方法【补充】AopContext作用 【步骤4】CglibMethodInvocation#proceed方法【步骤5】调…

文章目录

  • 【README】
  • 【步骤1】UserAppService调用userSupport.saveNewUser()
  • 【步骤2】获取到TransactionInterceptor
  • 【步骤3】chain不为空,接着执行CglibMethodInvocation#proceed方法
    • 【补充】AopContext作用
  • 【步骤4】CglibMethodInvocation#proceed方法
  • 【步骤5】调用ReflectiveMethodInvocation#proceed方法(反射方法调用类)
  • 【步骤6】调用 TransactionInterceptor#invoke(事务拦截器#invoke方法)
    • 【补充】TransactionInterceptor-事务拦截器源码
  • 【步骤7】调用TransactionAspectSupport#invokeWithinTransaction方法
  • 【步骤8】根据事务属性txAttr获取事务管理器,tm=JdbcTransactionManager
    • 【补充】事务管理器是什么?
  • 【步骤9】TransactionAspectSupport#invokeWithinTransaction()-在事务中执行业务逻辑(非常重要)
    • 【步骤9.1】按需创建事务-createTransactionIfNecessary()
    • 【补充】TransactionInfo事务信息定义
    • 【补充】TransactionStatus事务状态定义
    • 【步骤9.2】执行目标方法

【README】

1)声明式事务代码样例:

在这里插入图片描述

public interface UserMapper {UserPO qryUserById(@Param("id") String id);@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)void insertUser(UserPO userPO);
}public interface UserAccountMapper {@Transactional(propagation = Propagation.REQUIRED, rollbackFor = Exception.class)void insertUserAccount(UserAccountPO userAccountPO);
}

【代码解说】

  • 代码调用链路:UserAppService -> userSupport.saveNewUser -> userMapper.insertUser + userAccountMapper.insertUserAccount
  • userSupport.saveNewUser 带有 @Transactional 注解; 第1层(最外层)@Transactional标注的方法
    • userMapper.insertUser 带有 @Transactional 注解; 第2层@Transactional标注的方法1
    • userAccountMapper.insertUserAccount 带有 @Transactional 注解; 第2层@Transactional标注的方法2

2)@Transactional:事务注解,用于定义事务元数据,包括事务管理器名称,事务传播行为,超时时间(单位秒),是否只读,回滚的异常类型;

  • @Transactional可以标注类与方法,不管是标注类还是方法,@Transactional标注所在的类的bean都会被spring通过aop代理进行增强;
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
@Reflective
public @interface Transactional {@AliasFor("transactionManager")String value() default "";@AliasFor("value")String transactionManager() default "";String[] label() default {};Propagation propagation() default Propagation.REQUIRED;Isolation isolation() default Isolation.DEFAULT;int timeout() default -1;String timeoutString() default "";boolean readOnly() default false;Class<? extends Throwable>[] rollbackFor() default {};String[] rollbackForClassName() default {};Class<? extends Throwable>[] noRollbackFor() default {};String[] noRollbackForClassName() default {};
}


【步骤1】UserAppService调用userSupport.saveNewUser()

1)因为 userSupport中的saveNewUser方法被@Transaction标注,所以该bean被spring增强为aop代理,所以访问aop代理的入口方法intercept(),即CglibAopProxy#DynamicAdvisedInterceptor静态内部类的 intercept方法;

在这里插入图片描述



【步骤2】获取到TransactionInterceptor

在这里插入图片描述



【步骤3】chain不为空,接着执行CglibMethodInvocation#proceed方法

chain有一个元素: TransactionInterceptor-事务拦截器;

接着执行 467行:retVal = (new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy)).proceed();

在这里插入图片描述


【补充】AopContext作用

【补充455行代码】: AopContext实际上是带有ThreadContext的容器对象,用于存储代理对象;

public final class AopContext {private static final ThreadLocal<Object> currentProxy = new NamedThreadLocal("Current AOP proxy");private AopContext() {}public static Object currentProxy() throws IllegalStateException {Object proxy = currentProxy.get();if (proxy == null) {throw new IllegalStateException("Cannot find current proxy: Set 'exposeProxy' property on Advised to 'true' to make it available, and ensure that AopContext.currentProxy() is invoked in the same thread as the AOP invocation context.");} else {return proxy;}}@Nullablestatic Object setCurrentProxy(@Nullable Object proxy) {Object old = currentProxy.get();if (proxy != null) {currentProxy.set(proxy);} else {currentProxy.remove();}return old;}
}


【步骤4】CglibMethodInvocation#proceed方法

CglibMethodInvocation#proceed方法, 即Cglib方法调用类#proceed方法 (proceed=继续或进行或处理)

【CglibAopProxy#CglibMethodInvocation】

private static class CglibMethodInvocation extends ReflectiveMethodInvocation {public CglibMethodInvocation(Object proxy, @Nullable Object target, Method method, Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers, MethodProxy methodProxy) {super(proxy, target, method, arguments, targetClass, interceptorsAndDynamicMethodMatchers);}// 调用proceed @Nullablepublic Object proceed() throws Throwable {try {return super.proceed();} catch (RuntimeException var2) {throw var2;} catch (Exception var3) {if (!ReflectionUtils.declaresException(this.getMethod(), var3.getClass()) && !KotlinDetector.isKotlinType(this.getMethod().getDeclaringClass())) {throw new UndeclaredThrowableException(var3);} else {throw var3;}}}
}


【步骤5】调用ReflectiveMethodInvocation#proceed方法(反射方法调用类)

调用ReflectiveMethodInvocation#proceed方法, ReflectiveMethodInvocation=反射方法调用类

// ReflectiveMethodInvocation=反射方法调用类
// interceptorsAndDynamicMethodMatcher 是一个列表,包含一个元素 TransactionInterceptor 
// currentInterceptorIndex 初始值=-1 
public Object proceed() throws Throwable {if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {return this.invokeJoinpoint();} else {Object interceptorOrInterceptionAdvice = this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
// interceptorOrInterceptionAdvice 就是 TransactionInterceptor ,而不是 InterceptorAndDynamicMethodMatcherif (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {InterceptorAndDynamicMethodMatcher dm = (InterceptorAndDynamicMethodMatcher)interceptorOrInterceptionAdvice;Class<?> targetClass = this.targetClass != null ? this.targetClass : this.method.getDeclaringClass();return dm.matcher().matches(this.method, targetClass, this.arguments) ? dm.interceptor().invoke(this) : this.proceed();} else {return ((MethodInterceptor)interceptorOrInterceptionAdvice).invoke(this); // 调用到这里 }}
}

在这里插入图片描述

获取到的interceptorOrInterceptionAdvice的属性如下:

在这里插入图片描述



【步骤6】调用 TransactionInterceptor#invoke(事务拦截器#invoke方法)

调用 TransactionInterceptor#invoke(ReflectiveMethodInvocation), 传入的入参this是ReflectiveMethodInvocation-反射方法调用对象(包装了 UserSupportImpl#saveNewUser方法的代理对象)

【TransactionInterceptor#invoke】

public Object invoke(MethodInvocation invocation) throws Throwable {Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;Method var10001 = invocation.getMethod();Objects.requireNonNull(invocation);return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
}

上述 invocation::proceed中的invocation实际是 ReflectiveMethodInvocaion-反射方法调用类,ReflectiveMethodInvocaion封装了代理对象proxy,方法method等属性;

public class ReflectiveMethodInvocation implements ProxyMethodInvocation, Cloneable {protected final Object proxy;@Nullableprotected final Object target;protected final Method method;protected Object[] arguments;@Nullableprivate final Class<?> targetClass;@Nullableprivate Map<String, Object> userAttributes;protected final List<?> interceptorsAndDynamicMethodMatchers;private int currentInterceptorIndex = -1;protected ReflectiveMethodInvocation(Object proxy, @Nullable Object target, Method method, @Nullable Object[] arguments, @Nullable Class<?> targetClass, List<Object> interceptorsAndDynamicMethodMatchers) {this.proxy = proxy;this.target = target;this.targetClass = targetClass;this.method = BridgeMethodResolver.findBridgedMethod(method);this.arguments = AopProxyUtils.adaptArgumentsIfNecessary(method, arguments);this.interceptorsAndDynamicMethodMatchers = interceptorsAndDynamicMethodMatchers;}

【补充】TransactionInterceptor-事务拦截器源码

TransactionInterceptor继承自TransactionAspectSupport;

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {public TransactionInterceptor() {}public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) {this.setTransactionManager(ptm);this.setTransactionAttributeSource(tas);}@Nullablepublic Object invoke(MethodInvocation invocation) throws Throwable {Class<?> targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;Method var10001 = invocation.getMethod();Objects.requireNonNull(invocation);// 调用到这里, 注意最后一个入参是 invocation::proceed;return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);}private void writeObject(ObjectOutputStream oos) throws IOException {
//...}private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {// ...}
}


【步骤7】调用TransactionAspectSupport#invokeWithinTransaction方法

因为TransactionInterceptor 继承自TransactionAspectSupport; 而invokeWithinTransaction方法的最后一个入参invocation就是封装了目标方法,即UserSupportImpl#saveNewUser方法的包装对象ReflectiveMethodInvocation;

在这里插入图片描述

获取到的事务管理器类型是 JdbcTransactionManger, 而事务属性TransactionAttribute保存了注解@Transaction标注的方法的元数据,包括事务传播行为,隔离级别,超时时间,是否只读,事务管理器等属性; 而TransactionAttribute继承自TransactionDefinition-事务定义接口;

【TransactionAttribute】事务属性-TransactionAttribute定义

public interface TransactionAttribute extends TransactionDefinition {@NullableString getQualifier();Collection<String> getLabels();boolean rollbackOn(Throwable ex);
}

【TransactionAspectSupport#invokeWithinTransaction方法】执行到获取PlatformTransactionManager-平台事务管理器;

在这里插入图片描述



【步骤8】根据事务属性txAttr获取事务管理器,tm=JdbcTransactionManager

上述第7步执行到145行,接着判断tm(也就是JdbcTransactionManager)是否是ReactiveTransactionManager类型;

JdbcTransactionManager父类是DataSourceTransactionManager,而DataSourceTransactionManager父类是AbstractPlatformTransactionManager,而AbstractPlatformTransactionManager父类是PlatformTransactionManager;结论:tm(JdbcTransactionManager)不是CallbackPreferringPlatformTransactionManager,所以执行到160行;

在这里插入图片描述

又160行得到的ptm还是JdbcTransactionManager,与tm指向同一个对象,162行判断是否为CallbackPreferringPlatformTransactionManager类型不通过,接着执行第220行;

【补充】事务管理器是什么?

public class JdbcTransactionManager extends DataSourceTransactionManager;public class DataSourceTransactionManager extends AbstractPlatformTransactionManager implements ResourceTransactionManager, InitializingBean;public abstract class AbstractPlatformTransactionManager implements PlatformTransactionManager, ConfigurableTransactionManager, Serializable; 

【DataSourceTransactionManager】数据源事务管理器-方法列表

  • doBegin-开启事务
  • doCommit-提交事务
  • doGetTransaction-获取事务
  • doResume-恢复事务
  • doRollback-回滚事务
  • doSuspend-挂起事务;

在这里插入图片描述

【DataSourceTransactionManager父类AbstractPlatformTransactionManager】抽象平台事务管理器-部分方法列表

  • doBegin 开启事务
  • doCommit 提交
  • doGetTransation 获取事务
  • doResume 恢复事务
  • doSuspend 挂起事务
  • doRollback 回滚
  • setNestedTransactionAllowed -设置允许嵌套事务;


【步骤9】TransactionAspectSupport#invokeWithinTransaction()-在事务中执行业务逻辑(非常重要)

1)TransactionAspectSupport#invokeWithinTransaction()-在事务中执行业务逻辑,具体步骤如下(跳过了分支判断):

  • 步骤9.1:调用createTransactionIfNecessary方法,创建事务;
  • 步骤9.2:调用invocation.proceedWithInvocation(),执行具体业务逻辑(执行目标方法);
    • 步骤9.2.1(或有) : 抛出异常,执行completeTransactionAfterThrowing
  • 步骤9.3:执行完成(无论是否抛出异常),调用cleanupTransactionInfo()
  • 步骤9.4:判断返回值是否不为null 且 事务属性是否不为null
  • 步骤9.5:调用commitTransactionAfterReturning(),提交事务;

【TransactionAspectSupport#invokeWithinTransaction()】 在事务中调用;上游是TransactionInterceptor,而TransactionInterceptor是TransactionAspectSupport的子类; 源码如下。

protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass, final InvocationCallback invocation) throws Throwable {TransactionAttributeSource tas = this.getTransactionAttributeSource();TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;TransactionManager tm = this.determineTransactionManager(txAttr);if (this.reactiveAdapterRegistry != null && tm instanceof ReactiveTransactionManager rtm) {// tm类型是JdbcTransactionManager,所以不会执行到这里// ... return txSupport.invokeWithinTransaction(method, targetClass, invocation, txAttr, rtm);} else {PlatformTransactionManager ptm = this.asPlatformTransactionManager(tm);String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);if (txAttr != null && ptm instanceof CallbackPreferringPlatformTransactionManager cpptm) {// ptm类型是JdbcTransactionManager,所以不会执行到这里// ...} else {// 程序执行到这里 // 1 创建事务,【非常重要】 TransactionInfo txInfo = this.createTransactionIfNecessary(ptm, txAttr, joinpointIdentification);Object retVal;try {// 2 通过反射执行具体业务逻辑, invocation就是包装了业务方法UserSuuportImpl#saveUser()方法的调用对象 retVal = invocation.proceedWithInvocation();} catch (Throwable var22) {// 2.1 抛出异常 (或有)this.completeTransactionAfterThrowing(txInfo, var22);throw var22;} finally {// 3 最后清理事务信息 this.cleanupTransactionInfo(txInfo);}// 4 判断返回值是否不为null 且 事务属性是否不为null if (retVal != null && txAttr != null) {TransactionStatus status = txInfo.getTransactionStatus();if (status != null) {label185: {if (retVal instanceof Future) {// 5 若返回值为 Future类型(异步线程执行结果类)Future<?> future = (Future)retVal;if (future.isDone()) {try {future.get();} catch (ExecutionException var27) {if (txAttr.rollbackOn(var27.getCause())) {status.setRollbackOnly();}} catch (InterruptedException var28) {Thread.currentThread().interrupt();}break label185;}}if (vavrPresent && TransactionAspectSupport.VavrDelegate.isVavrTry(retVal)) {retVal = TransactionAspectSupport.VavrDelegate.evaluateTryFailure(retVal, txAttr, status);}}}}// 5 提交事务 this.commitTransactionAfterReturning(txInfo);return retVal;}}
}


【步骤9.1】按需创建事务-createTransactionIfNecessary()

TransactionAspectSupport#createTransactionIfNecessary()详情参见 spring声明式事务原理02-调用第1层@Transactional方法-按需创建事务createTransactionIfNecessary
在这里插入图片描述根据事务管理器+事务属性+aop连接点(切点)创建事务,如下:

protected TransactionInfo createTransactionIfNecessary(@Nullable PlatformTransactionManager tm, @Nullable TransactionAttribute txAttr, final String joinpointIdentification) {if (txAttr != null && ((TransactionAttribute)txAttr).getName() == null) {txAttr = new DelegatingTransactionAttribute((TransactionAttribute)txAttr) {public String getName() {return joinpointIdentification;}};}TransactionStatus status = null;if (txAttr != null) {if (tm != null) {// 通过事务管理器获取事务status = tm.getTransaction((TransactionDefinition)txAttr); } else if (this.logger.isDebugEnabled()) {this.logger.debug("Skipping transactional joinpoint [" + joinpointIdentification + "] because no transaction manager has been configured");}}// 准备事务信息TransactionInfo return this.prepareTransactionInfo(tm, (TransactionAttribute)txAttr, joinpointIdentification, status);
}

在这里插入图片描述


【补充】TransactionInfo事务信息定义

1)TransactionInfo是TransactionAspectSupport的 静态内部类,是一个聚合类,封装了事务相关的多个组件:

  • transactionManager:事务管理器(封装了事务提交,回滚功能)
  • TransactionAttribute:事务属性 (@Transaction注解元数据)
  • joinpointIdentification:切点标识(被@Transaction标注的目标方法的全限定名称)
  • TransactionStatus:事务状态 (封装获取事务状态的方法,如是否只读,是否回滚,是否保存点,事务是否完成,当前线程是否存在事务等)
  • oldTransactionInfo-上一个事务信息对象;

其中 oldTransactionInfo-上一个事务信息对象,是bindToThread()方法与restoreThreadLocalStatus() 需要用到的;

protected static final class TransactionInfo {@Nullableprivate final PlatformTransactionManager transactionManager;@Nullableprivate final TransactionAttribute transactionAttribute;private final String joinpointIdentification;@Nullableprivate TransactionStatus transactionStatus;@Nullableprivate TransactionInfo oldTransactionInfo;public TransactionInfo(@Nullable PlatformTransactionManager transactionManager, @Nullable TransactionAttribute transactionAttribute, String joinpointIdentification) {this.transactionManager = transactionManager;this.transactionAttribute = transactionAttribute;this.joinpointIdentification = joinpointIdentification;}public PlatformTransactionManager getTransactionManager() {Assert.state(this.transactionManager != null, "No PlatformTransactionManager set");return this.transactionManager;}@Nullablepublic TransactionAttribute getTransactionAttribute() {return this.transactionAttribute;}public String getJoinpointIdentification() {return this.joinpointIdentification;}public void newTransactionStatus(@Nullable TransactionStatus status) {this.transactionStatus = status;}@Nullablepublic TransactionStatus getTransactionStatus() {return this.transactionStatus;}public boolean hasTransaction() {return this.transactionStatus != null;}private void bindToThread() {this.oldTransactionInfo = (TransactionInfo)TransactionAspectSupport.transactionInfoHolder.get();TransactionAspectSupport.transactionInfoHolder.set(this);}private void restoreThreadLocalStatus() {TransactionAspectSupport.transactionInfoHolder.set(this.oldTransactionInfo);}    
}// 事务信息持有器(transactionInfoHolder)是一个ThreadLocal对象,
// 用于保存当前事务信息,及上一个事务信息(挂起时),以便恢复上一个事务信息;
private static final ThreadLocal<TransactionInfo> transactionInfoHolder = new NamedThreadLocal("Current aspect-driven transaction");

事务信息持有器(transactionInfoHolder):是一个ThreadLocal对象,用于保存当前事务信息,及上一个事务信息(挂起时),以便恢复上一个事务信息;

【补充】TransactionStatus事务状态定义

1)TransactionStatus继承自 TransactionExecution, SavepointManager

2)TransactionStatus封装了事务状态方法,包括是否有保存点,当前线程是否存在事务,当前线程是否存在新事务,是否只读,设置回滚状态或判断是否回滚,事务是否完成等状态方法;

3)封装的事务方法包括:

  • 保存点相关方法:包括 hasSavepoint , createSavepoint, rollbackToSavepoint, releaseSavepoint
  • 事务相关方法: 包括hasTransaction, isNewTransaction, isReadOnly, setRollbackOnly, isRollbackOnly, isCompleted;
  • 嵌套传播模式相关方法:isNested (嵌套模式底层原理是保存点)
public interface TransactionStatus extends TransactionExecution, SavepointManager, Flushable {default boolean hasSavepoint() {return false;}default void flush() {}
}
// 事务执行 
public interface TransactionExecution {default String getTransactionName() {return "";}default boolean hasTransaction() {return true;}default boolean isNewTransaction() {return true;}default boolean isNested() {return false;}default boolean isReadOnly() {return false;}default void setRollbackOnly() {throw new UnsupportedOperationException("setRollbackOnly not supported");}default boolean isRollbackOnly() {return false;}default boolean isCompleted() {return false;}
}
// 保存点管理器
public interface SavepointManager {Object createSavepoint() throws TransactionException;void rollbackToSavepoint(Object savepoint) throws TransactionException;void releaseSavepoint(Object savepoint) throws TransactionException;
}


【步骤9.2】执行目标方法

1)调用 invocation.proceedWithInvocation() 调用目标方法; invocation的类是 CglibMethodInvocation,即cglib代理方法调用类;

在这里插入图片描述

2)invocation.proceedWithInvocation():调用CglibMethodInvocation#proceed() 方法,又CglibMethodInvocation是封装了目标方法的cglib方法调用代理对象,所以接着会调用目标方法,即UserSupportImpl#saveNewUser()方法;

在这里插入图片描述

3)接着调用父类ReflectiveMethodInvocation的proceed()方法;

在这里插入图片描述

4)接着执行ReflectiveMethodInvocation#invokeJoinpoint方法,如下。

在这里插入图片描述

5)接着执行 AopUtils#invokeJoinpointUsingReflection() 方法

其中 originalMethod.invoke(target, args) 是通过反射调用具体的目标方法;

在这里插入图片描述

http://www.dtcms.com/wzjs/74675.html

相关文章:

  • 宣传 网站建设方案专业关键词优化平台
  • 网站怎么样做采集别人网站的文章seo百度点击软件
  • 网站制作深圳2345网址中国最好
  • 网站程序开发教程如何建网站不花钱
  • 外贸网站建设策划企业推广方案
  • 兰州网站建设运营方案网络软文范文
  • 四川网站建设价格百度最新秒收录方法2022
  • 视频直播网站建设费用最新免费网站收录提交入口
  • 南宁哪个公司做网站好上海野猪seo
  • 网站毕设代做2000元代理微信朋友圈广告
  • 网站换域名了怎么做301重定向品牌网络营销策划书
  • 美国做化工的b2b网站短视频搜索seo
  • 动态web网站开发技术软文例文 经典软文范例
  • 网页设计与网站建设期末考试题seo网络营销课程
  • 枣庄网站建设多少钱windows优化大师怎么彻底删除
  • 开网站平台需要多少钱武汉seo工作室
  • 网上书城网站开发外文参考文献优化技术
  • 卖东西的网站怎么建设真正免费的网站建站平台
  • vi全套设计包括什么宁波seo博客
  • 淘宝美工需要学什么软件重庆店铺整站优化
  • 刷粉网站开发网络广告策划的内容
  • 防录屏网站怎么做专业制作网站的公司哪家好
  • 泰安哪里有做网站app的病毒营销案例
  • 备案上个人网站和企业网站的区别可以放友情链接的网站
  • 做网站的计划书百度代理合作平台
  • 房屋设计装修app东莞seo建站优化工具
  • 广州网站建设推广服务小说百度风云榜
  • z-blog和wordpress哪个好用湖南企业seo优化推荐
  • seo网站模板百度大全
  • 网站建设 htmlseo服务哪家好