Spring声明式事务控制原理之声明式事务的重要组件在AOP中的应用

重要组件有:
1.InfrastructureAdvisorAutoProxyCreator 后置处理器
2.BeanFactoryTransactionAttributeSourceAdvisor 事务通知器
3.TransactionAttributeSource 事务属性解析器
4.TransactionInterceptor 事务拦截器,作为通知advice

1. InfrastructureAdvisorAutoProxyCreator的作用

InfrastructureAdvisorAutoProxyCreator实现了SmartInstantiationAwareBeanPostProcessor是一个后置处理器,在bean创建过程的最后一步会调用InfrastructureAdvisorAutoProxyCreator的postProcessAfterInitialization方法对bean进行代理增强
AbstractAutowireCapableBeanFactory.class
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException {
     

		Object result = existingBean;
		for (BeanPostProcessor processor : getBeanPostProcessors()) {
     
			// 遍历执行bean后置处理器的postProcessAfterInitialization方法
			Object current = processor.postProcessAfterInitialization(result, beanName);
			if (current == null) {
     
				return result;
			}
			result = current;
		}
		return result;
	}

2. BeanFactoryTransactionAttributeSourceAdvisor的作用

这是一个Advisor(通知器),在AbstractAutoProxyCreator#wrapIfNecessary方法中获取当前bean相关的全部切面,用于代理类的生成
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
     
		//
		if (StringUtils.hasLength(beanName) && this.targetSourcedBeans.contains(beanName)) {
     
			return bean;
		}
		// 当前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.
		// 获取当前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;
		}
		// 当前bean无切面
		this.advisedBeans.put(cacheKey, Boolean.FALSE);
		return bean;
	}

3.TransactionAttributeSource的作用

主要作用解析某方法中是否包含@Transactional,解析Transactional注解的各个属性封装成配置类备用;有两个重要地方用到第一个地方用来判断bean里是否包含@Transactional,以决定是否为此bean进行事务代理增强;第二个地方用来判断bean具体的方法上是否包含@Transactional,以决定是否对此方法进行事务拦截

第一个:在2中获取当前bean相关的全部切面的AbstractAdvisorAutoProxyCreator#getAdvicesAndAdvisorsForBean#findEligibleAdvisors#findAdvisorsThatCanApply里用到

AbstractAdvisorAutoProxyCreator.class
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();
	}


protected List<Advisor> findEligibleAdvisors(Class<?> beanClass, String beanName) {
     
		// 获取容器里全部切面
		List<Advisor> candidateAdvisors = findCandidateAdvisors();
		// 过滤切入当前bean的切面
		List<Advisor> eligibleAdvisors = findAdvisorsThatCanApply(candidateAdvisors, beanClass, beanName);
		extendAdvisors(eligibleAdvisors);
		if (!eligibleAdvisors.isEmpty()) {
     
			// 切面按指定顺序排序
			eligibleAdvisors = sortAdvisors(eligibleAdvisors);
		}
		return eligibleAdvisors;
	}

protected List<Advisor> findAdvisorsThatCanApply(
			List<Advisor> candidateAdvisors, Class<?> beanClass, String beanName) {
     

		ProxyCreationContext.setCurrentProxiedBeanName(beanName);
		try {
     
			// 过滤于当前Bean无关的Advisor(通知器)
			return AopUtils.findAdvisorsThatCanApply(candidateAdvisors, beanClass);
		}
		finally {
     
			ProxyCreationContext.setCurrentProxiedBeanName(null);
		}
	}
AopUtils.class
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;
	}

// 用到了advisor的切入点PointCut来判断这个bean里的那个方法符合切入点,也就是存在@Transactional注解,这里切入点判断某方法是否包含@Transactional注解时用到了TransactionAttributeSource
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) {
     
			PointcutAdvisor pca = (PointcutAdvisor) advisor;
			return canApply(pca.getPointcut(), targetClass, hasIntroductions);
		}
		else {
     
			// It doesn't have a pointcut so we assume it applies.
			return true;
		}
	}

第二个地方:以JDK动态代理举例在代理类调用方法时会进入JdkDynamicAopProxy的invoke方法,在此方法里会获取当前方法的拦截器链,然后组装创建一个方法执行器,用来管理各个拦截方法按顺序调用,如第一个地方一样此处用到了TransactionAttributeSource来判断此方法是否符合BeanFactoryTransactionAttributeSourceAdvisor的切入点即是否有@Transactional注解

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 {
     
			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);

			// Get the interception chain for this method.
			// 获取方法的拦截器链
			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 {
     
				// 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();
			}

			// 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);
			}
		}
	}

4.TransactionInterceptor

这是一个方法拦截器也可以理解为是一个定义了事务处理的横切逻辑的通知advice,主要用在代理对象执行带有@Transactional的方法时调用invoke方法对原方法进行拦截增强,织入事务横切逻辑(作为3中第二个地方拦截器链的一员)
TransactionInterceptor.class
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);
	}

进入invokeWithinTransaction方法

TransactionAspectSupport.class
protected Object invokeWithinTransaction(Method method, @Nullable Class<?> targetClass,
			final InvocationCallback invocation) throws Throwable {
     

		// If the transaction attribute is null, the method is non-transactional.
		// 获取事务属性解析器ProxyTransactionManagementConfiguration中注入
		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;
			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;
			}
		}
	}

你可能感兴趣的:(Spring,#aop,spring,aop)