前言

如果这是你第二次看到师长,说明你在觊觎我的美色!

点赞+关注再看,养成习惯

没别的意思,就是需要你的窥屏_

专车介绍**

该趟专车是开往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进阶架构师】)

最新文章

  1. [Bundling and Minification ] 三、缩小
  2. javascript之原型模式学习
  3. motto5
  4. java基础知识回顾之javaIO类--File类应用:获取指定目录下面的指定扩展名的文件,将文件的绝对路径写入到目的文件当中
  5. C# Tcp协议收发数据
  6. Kerberos验证过程
  7. 1.移植uboot-分析uboot启动流程(详解)
  8. 自适应rem.js
  9. ABAQUS复合材料
  10. iOS.Info.plist
  11. RabbitMq简单应用
  12. Codeforces Round #292 (Div. 1)A. Drazil and Factorial 构造
  13. 10.6 监控io性能 10.7 free命令 10.8 ps命令 10.9 查看网络状态 10.10 linux下抓包
  14. Android开源库集合(控件)
  15. 数据库Job定时任务
  16. HDU 5233 Gunner II 离散化
  17. linux 文件上传&amp;软件安装(rpm)
  18. 第23天:js-数据类型转换
  19. 基于Nginx的开墙方案
  20. viewpagerindicator+UnderlinePageIndicator+ viewpage切换

热门文章

  1. Flink中发送端反压以及Credit机制(源码分析)
  2. python学习之【第九篇】:Python中的变量作用域
  3. Windows7下安装Linux双操作系统
  4. MQ基本应用场景
  5. docker——数据卷volume:文件共享
  6. 总结一下 IEnumerable 的例子
  7. docker初解
  8. LoadRunner具体流程
  9. W与V模型的联系与区别
  10. 如何解决UNMOUNTABLE BOOT VALUME