spring事务/和aop的执行过程

1、开启事务的方式

(1) 通过代码的方式创建事务,我们需要在代码中调用beginTransaction()、commit()、rollback()等事务管理相关的方法,这就是编程式事务管理。
(2) 基于@Transactional的声明式事务管理
(3) 基于aspectj Aop 配置事务管理
(4) 基于 TransactionProxyFactoryBean的声明式事务

(1)通过代码的方式创建事务

@Autowired
private DataSourceTransactionManager transactionManager;
// 事务回滚
transactionManager.rollback(status);
// 事务提交
transactionManager.commit(status);
//1.获取事务定义
DefaultTransactionDefinition def = new DefaultTransactionDefinition();
//2.设置事务隔离级别,开启新事务
def.setPropagationBehavior(TransactionDefinition.PROPAGATION_REQUIRES_NEW);
//3.获得事务状态
TransactionStatus status = transactionManager.getTransaction(def);

(2)、 基于@Transactional的声明式事务管理

xml中的配置,以及java代码中对事务的实现

 <!-- 事务管理器 -->
  <bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
      <property name="dataSource" ref="dataSource"></property>
  </bean>
  
  <!-- 启用事务注解 -->
  <tx:annotation-driven transaction-manager="myTracnsactionManager"/>
    @Transactional
    public void testTransaction(User user) {
        userMapper.insert(user);
        //userMapper.deleteByPrimaryKey(user.getId());
        Integer rst = Integer.valueOf("asdf");
    }

(3) 基于aspectj Aop 配置事务管理

<!-- 事务管理器 -->
    <bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <tx:advice id="txAdvice" transaction-manager="myTracnsactionManager">
        <tx:attributes>
            <!-- 为连接点指定事务属性 -->
            <tx:method name="add*" isolation="DEFAULT" propagation="REQUIRED"/>
            <tx:method name="buyStock" isolation="DEFAULT" propagation="REQUIRED" rollback-for="BuyStockException"/>
        </tx:attributes>
    </tx:advice>
    
    <aop:config>
        <!-- 切入点配置 -->
        <aop:pointcut expression="execution(* *..service.*.*(..))" id="point"/>
        <aop:advisor advice-ref="txAdvice" pointcut-ref="point"/>
    </aop:config>

(4) 基于 TransactionProxyFactoryBean的声明式事务

 <!-- 事务管理器 -->
    
    <bean id="myTracnsactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
        <property name="dataSource" ref="dataSource"></property>
    </bean>
    
    <!-- 事务代理工厂 -->
    <!-- 生成事务代理对象 -->
    <bean id="serviceProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean">
        <property name="transactionManager" ref="myTracnsactionManager"></property>
        <property name="target" ref="buyStockService"></property>
        <property name="transactionAttributes">
            <props>
                <!-- 主要 key 是方法   
                    ISOLATION_DEFAULT  事务的隔离级别
                    PROPAGATION_REQUIRED  传播行为
                -->
                <prop key="add*">ISOLATION_DEFAULT,PROPAGATION_REQUIRED</prop>
                <!-- -Exception 表示发生指定异常回滚,+Exception 表示发生指定异常提交 -->
                <prop key="buyStock">ISOLATION_DEFAULT,PROPAGATION_REQUIRED,-BuyStockException</prop>
            </props>
        </property>
    </bean>

事务实现原理

1、在spring初始化的时候会先通过xml的配置获取到需要处理事务的类和方法,configureAutoProxyCreator会创建3个spring 事务管理需要的3个beanfactory

public static void configureAutoProxyCreator(Element element, ParserContext parserContext) {
			AopNamespaceUtils.registerAutoProxyCreatorIfNecessary(parserContext, element);
			//
			String txAdvisorBeanName = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME;
			if (!parserContext.getRegistry().containsBeanDefinition(txAdvisorBeanName)) {
				Object eleSource = parserContext.extractSource(element);

				// Create the TransactionAttributeSource definition.
				RootBeanDefinition sourceDef = new RootBeanDefinition(
						"org.springframework.transaction.annotation.AnnotationTransactionAttributeSource");
				sourceDef.setSource(eleSource);
				sourceDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				String sourceName = parserContext.getReaderContext().registerWithGeneratedName(sourceDef);

				// Create the TransactionInterceptor definition.
				RootBeanDefinition interceptorDef = new RootBeanDefinition(TransactionInterceptor.class);
				interceptorDef.setSource(eleSource);
				interceptorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				registerTransactionManager(element, interceptorDef);
				interceptorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				String interceptorName = parserContext.getReaderContext().registerWithGeneratedName(interceptorDef);

				// Create the TransactionAttributeSourceAdvisor definition.
				RootBeanDefinition advisorDef = new RootBeanDefinition(BeanFactoryTransactionAttributeSourceAdvisor.class);
				advisorDef.setSource(eleSource);
				advisorDef.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
				advisorDef.getPropertyValues().add("transactionAttributeSource", new RuntimeBeanReference(sourceName));
				advisorDef.getPropertyValues().add("adviceBeanName", interceptorName);
				if (element.hasAttribute("order")) {
					advisorDef.getPropertyValues().add("order", element.getAttribute("order"));
				}
				parserContext.getRegistry().registerBeanDefinition(txAdvisorBeanName, advisorDef);

				CompositeComponentDefinition compositeDef = new CompositeComponentDefinition(element.getTagName(), eleSource);
				compositeDef.addNestedComponent(new BeanComponentDefinition(sourceDef, sourceName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(interceptorDef, interceptorName));
				compositeDef.addNestedComponent(new BeanComponentDefinition(advisorDef, txAdvisorBeanName));
				parserContext.registerComponent(compositeDef);
			}
		}
	}

2、然后在创建bean的时候,将需要注入事务的类和方法进行增强在createBean方法中的
这行代码Object bean = resolveBeforeInstantiation(beanName, mbdToUse);,然后在调用applyBeanPostProcessorsBeforeInstantiation方法,然后在调用getAdvicesAndAdvisorsForBean

@Nullable
	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {
		Object bean = null;
		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {
			// Make sure bean class is actually resolved at this point.
			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
				Class<?> targetType = determineTargetType(beanName, mbd);
				if (targetType != null) {
					bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
					if (bean != null) {
						bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
					}
				}
			}
			mbd.beforeInstantiationResolved = (bean != null);
		}
		return bean;
	}
		@Nullable
	protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) {
		for (BeanPostProcessor bp : getBeanPostProcessors()) {
			if (bp instanceof InstantiationAwareBeanPostProcessor) {
				InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
				Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName);
				if (result != null) {
					return result;
				}
			}
		}
		return null;
	}
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator
在调用
@Override
	public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) {
		Object cacheKey = getCacheKey(beanClass, beanName);

		if (!StringUtils.hasLength(beanName) || !this.targetSourcedBeans.contains(beanName)) {
			if (this.advisedBeans.containsKey(cacheKey)) {
				return null;
			}
			if (isInfrastructureClass(beanClass) || shouldSkip(beanClass, beanName)) {
				this.advisedBeans.put(cacheKey, Boolean.FALSE);
				return null;
			}
		}

		// Create proxy here if we have a custom TargetSource.
		// Suppresses unnecessary default instantiation of the target bean:
		// The TargetSource will handle target instances in a custom fashion.
		TargetSource targetSource = getCustomTargetSource(beanClass, beanName);
		if (targetSource != null) {
			if (StringUtils.hasLength(beanName)) {
				this.targetSourcedBeans.add(beanName);
			}
			Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(beanClass, beanName, targetSource);
			Object proxy = createProxy(beanClass, beanName, specificInterceptors, targetSource);
			this.proxyTypes.put(cacheKey, proxy.getClass());
			return proxy;
		}

		return null;
	}
org.springframework.aop.framework.autoproxy.AbstractAdvisorAutoProxyCreator
@Override
	@Nullable
	//获取bean对应的增强器
	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();
	}

3、在JdkDynamicAopProxy或CglibAopProxy代理bean执行方法时会执行下面的过程,列入:JdkDynamicAopProxy在执行userService.testTransaction代理bean的方法时会调用invoke然后会通过

			//获取可以应用到此方法上的Interceptor列表
			List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

这段代码获取执行这个方法,需要被spring中配置的aop的切面进行拦截,其中事务配置的切面需要执行的事务的类为TransactionInterceptor,然后在通过下面的这段代码取执行事务

//如果没有可以应用到此方法的通知(Interceptor),此直接反射调用 method.invoke(target, args)
			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 {
				// We need to create a method invocation...
				//创建MethodInvocation
				invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
				// Proceed to the joinpoint through the interceptor chain.
				retVal = invocation.proceed();
			}
//通过这个方法取执行,chain中剩余的拦截器
public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		//如果Interceptor执行完了,则执行joinPoint
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		//如果要动态匹配joinPoint
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			// Evaluate dynamic method matcher here: static part will already have
			// been evaluated and found to match.
			InterceptorAndDynamicMethodMatcher dm =
					(InterceptorAndDynamicMethodMatcher) interceptorOrInterceptionAdvice;
			//动态匹配:运行时参数是否满足匹配条件
			if (dm.methodMatcher.matches(this.method, this.targetClass, this.arguments)) {
				//执行拦截器中的invoke即TransactionInterceptor中invoke的方法
				return dm.interceptor.invoke(this);
			}
			else {
				// Dynamic matching failed.
				// Skip this interceptor and invoke the next in the chain.
				//动态匹配失败时,略过当前Intercetpor,调用下一个Interceptor
				return proceed();
			}
		}
		else {
			// It's an interceptor, so we just invoke it: The pointcut will have
			// been evaluated statically before this object was constructed.
			//执行当前Intercetpor
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

然后通过 dm.interceptor.invoke(this)取调用TransactionInterceptor中invoke的方法,实际上是调用org.springframework.transaction.interceptor.TransactionAspectSupport#invokeWithinTransaction这个方法

@Nullable
	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);
		//获取beanfactory中的transactionManager
		final PlatformTransactionManager tm = determineTransactionManager(txAttr);
		//构造方法唯一标识(类.方法,如service.UserServiceImpl.save)
		final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
		//声明事务处理
		if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			//创建TransactionInfo
			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;
			}
		}
	}

最后在所有的interceptor都执行完了之后通过
最后通过下面这段代码来执行被代理的对象需要执行的方法

@Override
	@Nullable
	public Object proceed() throws Throwable {
		//	We start with an index of -1 and increment early.
		//如果Interceptor执行完了,则执行joinPoint
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			return invokeJoinpoint();
		}
		.......
	}

aop执行的过程

在spring执行代理类的方法是列入:CglibAopProxy时是通过intercept方法去执行的代理方法,在执行的过程中 会获取到一个
List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
在这里插入图片描述
这些类都实现了MethodInterceptor这个接口这个接口里有个invoke方法
然后spring 会到一个,invocation这个是执行invoke方法本身的对象,这里是一个递归调用

@FunctionalInterface
public interface MethodInterceptor extends Interceptor {
	Object invoke(MethodInvocation invocation) throws Throwable;
}
public Object proceed() throws Throwable {
		// We start with an index of -1 and increment early.
		if (this.currentInterceptorIndex == this.interceptorsAndDynamicMethodMatchers.size() - 1) {
			//执行被代理类的方法
			return invokeJoinpoint();
		}

		Object interceptorOrInterceptionAdvice =
				this.interceptorsAndDynamicMethodMatchers.get(++this.currentInterceptorIndex);
		if (interceptorOrInterceptionAdvice instanceof InterceptorAndDynamicMethodMatcher) {
			//此处求值动态方法匹配器:静态部分将已具有
			//已评估并发现匹配。
			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 {
				//动态匹配失败。
				//跳过这个拦截器并调用链中的下一个拦截器。
				return proceed();
			}
		}
		else {
			//它是一个拦截器,所以我们调用它:切入点将
			//在构造此对象之前进行静态计算。
			return ((MethodInterceptor) interceptorOrInterceptionAdvice).invoke(this);
		}
	}

invoke示例代码 org.springframework.aop.interceptor.ExposeInvocationInterceptor#invoke

@Override
	public Object invoke(MethodInvocation mi) throws Throwable {
		MethodInvocation oldInvocation = invocation.get();
		invocation.set(mi);
		try {
			//最后又会回到 org.springframework.aop.framework.CglibAopProxy.CglibMethodInvocation中的proceed,然后在去调用org.springframework.aop.framework.ReflectiveMethodInvocation#proceed
			return mi.proceed();
		}
		finally {
			invocation.set(oldInvocation);
		}
	}

proceed()执行的拦截器的过程
通过这里代码我们可以看出这里存在一个递归的调用,没调用一次,计数器[this.currentInterceptorIndex]就+1,在执行list中的拦截器时每个拦截器都会去调用invoke方法,然后在调用invoke方法时都会去调用invocation.proceedWithInvocation();会重新进入到proceed()方法,就这样重复的执行直到chain中的拦截器知道全部全部执行完

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值