万隆的笔记 万隆的笔记
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
博文索引
笔试面试
  • 在线学站

    • 菜鸟教程 (opens new window)
    • 入门教程 (opens new window)
    • Coursera (opens new window)
  • 在线文档

    • w3school (opens new window)
    • Bootstrap (opens new window)
    • Vue (opens new window)
    • 阿里开发者藏经阁 (opens new window)
  • 在线工具

    • tool 工具集 (opens new window)
    • bejson 工具集 (opens new window)
    • 文档转换 (opens new window)
  • 更多在线资源
  • Changlog
  • Aboutme
GitHub (opens new window)
  • Spring

    • Spring简介
    • Spring核心思想
    • 手写实现IoC和AOP
    • Spring Web与Bean装配
    • Spring Transaction
    • Spring Validation
    • Spring IoC基础应用
    • Spring IoC高级特性
    • Spring IoC源码剖析
    • Spring AOP应用
    • Spring AOP声明式事务
    • Spring AOP源码剖析
      • 代理对象创建
      • Spring声明式事务控制
  • SprinvMVC

  • SpringBoot

  • Spring
  • Spring
2023-02-18
目录

Spring AOP源码剖析

# Spring AOP源码剖析

# 代理对象创建

# AOP基础⽤例准备

@Component
public class AopBean {
    public void test(){
        System.out.println("java learn aop ......");
    }
}

Aspect定义

/**
 * @author jack.wen
 * @since 2023/12/2 22:13
 */
@Component
@Aspect
public class AopBeanAspect {

    @Pointcut("execution(* com.example.spring.learn.AopBean.*(..))")
    public void pointcut(){
    }

    @Before("pointcut()")
    public void before() {
        System.out.println("before method ......");
    } 

}

测试⽤例

public class AopTest {

    @Test
    public void testAopProxyBuild() throws Exception {
        ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
        AopBean aopBean = (AopBean) applicationContext.getBean("aopBean");
        aopBean.test();
    }
    
}

# 时机点分析

我们发现在 getBean 之前,AopBean代理对象已经产⽣(即在第⼀⾏初始化代码中完成),所以我们断定,容器初始化过程中⽬标Bean已经完成了代理,返回了代理对象。

spring_src_aop_1

# 代理对象创建流程

核心流程前瞻:

AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object,
org.springframework.beans.factory.support.RootBeanDefinition)
--> AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
  --> AbstractAutoProxyCreator#postProcessAfterInitialization
  	--> AbstractAutoProxyCreator#createProxy
  		--> ProxyFactory#getProxy(java.lang.ClassLoader)
  			--> ProxyCreatorSupport#createAopProxy
  				--> ProxyCreatorSupport#getAopProxyFactory
  					--> DefaultAopProxyFactory#createAopProxy
/**
* AbstractAutowireCapableBeanFactory#initializeBean
* 初始化Bean, 包括Bean后置处理器初始化,Bean的⼀些初始化⽅法的执⾏init-method,Bean的实现的声明周期相关接⼝的属性注⼊
*/
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
		if (System.getSecurityManager() != null) {
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else {
			// 调用实现了Aware接口的方法
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		if (mbd == null || !mbd.isSynthetic()) {
			// before,  执⾏所有的BeanPostProcessor#postProcessBeforeInitialization 初始化之前的处理器⽅法
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try {
			// init,执⾏afterPropertiesSet(实现了InitializingBean接⼝)⽅法和调用bean的initMethods
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) {
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}
		if (mbd == null || !mbd.isSynthetic()) {
			// after, 后置处理器
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		return wrappedBean;
	}
/**
* AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
*/
public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
    throws BeansException {

  Object result = existingBean;
  // 循环执⾏后置处理器,  这里重点关注创建代理对象的后置处理器AbstractAutoProxyCreator
  for (BeanPostProcessor processor : getBeanPostProcessors()) {
    Object current = processor.postProcessAfterInitialization(result, beanName);
    if (current == null) {
      return result;
    }
    result = current;
  }
  return result;
}
/**
* AbstractAutoProxyCreator#postProcessAfterInitialization,创建代理对象的后置处理器
*/
public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) {
  if (bean != null) {
    // 检查下该类是否已经暴露过了(可能已经创建了,⽐如A依赖B时,创建A时候,就会先去创建B。
    // 当真正需要创建B时,就没必要再代理⼀次已经代理过的对象),避免重复创建
    Object cacheKey = getCacheKey(bean.getClass(), beanName);
    if (this.earlyProxyReferences.remove(cacheKey) != bean) {
      return wrapIfNecessary(bean, beanName, cacheKey);
    }
  }
  return bean;
}
/**
* AbstractAutoProxyCreator#wrapIfNecessary
*/
protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
  // targetSourcedBeans包含,说明前⾯创建过
  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.
  // 得到所有候选Advisor,对Advisors和bean的⽅法双层遍历匹配,最终得到⼀个 List<Advisor>,即specificInterceptors
  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,为指定 bean 创建代理对象
*/
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 proxyFactory = new ProxyFactory();
		proxyFactory.copyFrom(this);

		// 根据⼀些情况判断是否要设置proxyTargetClass=true
		if (proxyFactory.isProxyTargetClass()) {
			// Explicit handling of JDK proxy targets and lambdas (for introduction advice scenarios)
			if (Proxy.isProxyClass(beanClass) || ClassUtils.isLambdaClass(beanClass)) {
				// Must allow for introductions; can't just set interfaces to the proxy's interfaces only.
				for (Class<?> ifc : beanClass.getInterfaces()) {
					proxyFactory.addInterface(ifc);
				}
			}
		}
		else {
			// No proxyTargetClass flag enforced, let's apply our default checks...
			if (shouldProxyTargetClass(beanClass, beanName)) {
				proxyFactory.setProxyTargetClass(true);
			}
			else {
				evaluateProxyInterfaces(beanClass, proxyFactory);
			}
		}

		// 把指定和通⽤拦截对象合并, 并都适配成Advisor
		Advisor[] advisors = buildAdvisors(beanName, specificInterceptors);
		proxyFactory.addAdvisors(advisors);
		// 设置参数
		proxyFactory.setTargetSource(targetSource);
		customizeProxyFactory(proxyFactory);

		proxyFactory.setFrozen(this.freezeProxy);
		if (advisorsPreFiltered()) {
			proxyFactory.setPreFiltered(true);
		}

		// Use original ClassLoader if bean class not locally loaded in overriding class loader
		ClassLoader classLoader = getProxyClassLoader();
		if (classLoader instanceof SmartClassLoader && classLoader != beanClass.getClassLoader()) {
			classLoader = ((SmartClassLoader) classLoader).getOriginalClassLoader();
		}
		// 上⾯准备做完就开始创建代理
		return proxyFactory.getProxy(classLoader);
	}

接下来看ProxyFactory#getProxy(java.lang.ClassLoader):

public Object getProxy(@Nullable ClassLoader classLoader) {
  // ⽤ProxyFactory创建AopProxy, 然后⽤AopProxy创建Proxy, 所以这⾥重要的是看获取的AopProxy对象是什么,
  // 然后进去看怎么创建动态代理, 我们知道的是提供了两种:jdk proxy, cglib
  return createAopProxy().getProxy(classLoader);
}

先看ProxyCreatorSupport#createAopProxy怎么创建Proxy的:

protected final synchronized AopProxy createAopProxy() {
  if (!this.active) {
    activate();
  }
  // 先获取创建AopProxy的⼯⼚, 再由此创建AopProxy,
  return getAopProxyFactory().createAopProxy(this);
}

// 默认返回的是DefaultAopProxyFactory
public AopProxyFactory getAopProxyFactory() {
  return this.aopProxyFactory;
}

AopProxyFactory默认是DefaultAopProxyFactory,看他的createAopProxy⽅法:

public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
		// 这⾥决定创建代理对象是⽤JDK Proxy,还是⽤ Cglib
		// 从使⽤⽅⾯使⽤来说:设置proxyTargetClass=true强制使⽤Cglib 代理,
		// 什么参数都不设并且对象类实现了接⼝则默认⽤JDK代理,如果没有实现接⼝则也必须⽤Cglib
		if (!NativeDetector.inNativeImage() &&
				(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) || ClassUtils.isLambdaClass(targetClass)) {
				return new JdkDynamicAopProxy(config);
			}
			return new ObjenesisCglibAopProxy(config);
		}
		else {
			return new JdkDynamicAopProxy(config);
		}
	}

现在回过头看getProxy的实现:

/**
*  ProxyFactory#getProxy(java.lang.ClassLoader)
*  --> CglibAopProxy#getProxy(java.lang.ClassLoader)
*/
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 (rootClass.getName().contains(ClassUtils.CGLIB_CLASS_SEPARATOR)) {
      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...
    // 配置 Cglib 增强
    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 ClassLoaderAwareGeneratorStrategy(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);
  }
}

# Spring声明式事务控制

声明式事务很⽅便,尤其纯注解模式,仅仅⼏个注解就能控制事务了,那这些注解都做了什么?

  • @EnableTransactionManagement
  • @Transactional

核心流程前瞻:

@EnableTransactionManagement注解
--> 通过@import引⼊了TransactionManagementConfigurationSelector类它的selectImports⽅法导⼊了另外两个类:AutoProxyRegistrar和ProxyTransactionManagementConfiguration
	--> AutoProxyRegistrar类分析,⽅法registerBeanDefinitions中,引⼊了其他类,通过AopConfigUtils.registerAutoProxyCreatorIfNecessary(registry)引⼊InfrastructureAdvisorAutoProxyCreator,
它继承了AbstractAutoProxyCreator,是⼀个后置处理器类
	--> ProxyTransactionManagementConfiguration类分析, 是⼀个添加了@Configuration注解的配置类,注册事务增强器(注⼊属性解析器、事务拦截器)
		- 属性解析器:AnnotationTransactionAttributeSource,内部持有了⼀个解析器集合Set<TransactionAnnotationParser> annotationParsers; 具体使⽤的是SpringTransactionAnnotationParser解析器,⽤来解析@Transactional的事务属性
    - 事务拦截器:TransactionInterceptor实现了MethodInterceptor接⼝,该通⽤拦截会在产⽣代理对象之前和aop增强合并,最终⼀起影响到代理对象,TransactionInterceptor的invoke⽅法中invokeWithinTransaction会触发原有业务逻辑调⽤(增强事务)

# @EnableTransactionManagement

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Import(TransactionManagementConfigurationSelector.class)
public @interface EnableTransactionManagement {

	boolean proxyTargetClass() default false;

	AdviceMode mode() default AdviceMode.PROXY;

	int order() default Ordered.LOWEST_PRECEDENCE;

}

@EnableTransactionManagement 注解使⽤ @Import 标签引⼊了TransactionManagementConfigurationSelector类,这个类⼜向容器中导⼊了两个重要的组件AutoProxyRegistrar、ProxyTransactionManagementConfiguration。

public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
  
  @Override
	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 组件,AutoProxyRegistrar 类的 registerBeanDefinitions ⽅法中⼜注册了⼀个组件

    public class AutoProxyRegistrar implements ImportBeanDefinitionRegistrar {
    
    	private final Log logger = LogFactory.getLog(getClass());
    
    	@Override
    	public void registerBeanDefinitions(AnnotationMetadata importingClassMetadata, BeanDefinitionRegistry registry) {
    		boolean candidateFound = false;
    		Set<String> annTypes = importingClassMetadata.getAnnotationTypes();
    		for (String annType : annTypes) {
    			AnnotationAttributes candidate = AnnotationConfigUtils.attributesFor(importingClassMetadata, annType);
    			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;
    					}
    				}
    			}
    		}
    		if (!candidateFound && logger.isInfoEnabled()) {
    			String name = getClass().getSimpleName();
    			logger.info(String.format("%s was imported but no annotations were found " +
    					"having both 'mode' and 'proxyTargetClass' attributes of type " +
    					"AdviceMode and boolean respectively. This means that auto proxy " +
    					"creator registration and configuration may not have occurred as " +
    					"intended, and components may not be proxied as expected. Check to " +
    					"ensure that %s has been @Import'ed on the same class where these " +
    					"annotations are declared; otherwise remove the import of %s " +
    					"altogether.", name, name, name));
    		}
    	}
    
    }
    

    进⼊ AopConfigUtils.registerAutoProxyCreatorIfNecessary ⽅法,一层层调用后我们发现,注册了⼀个叫做 InfrastructureAdvisorAutoProxyCreator 的 Bean,⽽这个类是 AbstractAutoProxyCreator 的⼦类,实现了 SmartInstantiationAwareBeanPostProcessor 接⼝:

    public abstract class AopConfigUtils {
      // ......
    	@Nullable
    	public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
    		return registerAutoProxyCreatorIfNecessary(registry, null);
    	}
    
    	@Nullable
    	public static BeanDefinition registerAutoProxyCreatorIfNecessary(
    			BeanDefinitionRegistry registry, @Nullable Object source) {
    		// 最终注册的组件
    		return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
    	}
      // ......
    }
    
    public interface SmartInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessor {
    
    	@Nullable
    	default Class<?> predictBeanType(Class<?> beanClass, String beanName) throws BeansException {
    		return null;
    	}
    
    	@Nullable
    	default Constructor<?>[] determineCandidateConstructors(Class<?> beanClass, String beanName)
    			throws BeansException {
    
    		return null;
    	}
    
    	default Object getEarlyBeanReference(Object bean, String beanName) throws BeansException {
    		return bean;
    	}
    
    }
    

    我再看看InfrastructureAdvisorAutoProxyCreator的继承体系:它实现了SmartInstantiationAwareBeanPostProcessor,说明这是⼀个后置处理器,⽽且跟 Spring AOP 开启@EnableAspectJAutoProx 时注册的AnnotationAwareAspectJProxyCreator实现的是同⼀个接⼝,所以说,声明式事务是 SpringAOP 思想的⼀种应⽤。

    InfrastructureAdvisorAutoProxyCreator.png

  • ProxyTransactionManagementConfiguration 组件,ProxyTransactionManagementConfiguration是⼀个容器配置类,注册了⼀个组件transactionAdvisor,称为事务增强器,然后在这个事务增强器中⼜注⼊了两个属性:

    • transactionAttributeSource,属性解析器
    • transactionInterceptor,事务拦截器。
    @Configuration(proxyBeanMethods = false)
    @Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    
    	@Bean(name = TransactionManagementConfigUtils.TRANSACTION_ADVISOR_BEAN_NAME)
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	public BeanFactoryTransactionAttributeSourceAdvisor transactionAdvisor(
    			TransactionAttributeSource transactionAttributeSource, TransactionInterceptor transactionInterceptor) {
    		// 事务增强器
    		BeanFactoryTransactionAttributeSourceAdvisor advisor = new BeanFactoryTransactionAttributeSourceAdvisor();
    		// 向事务增强器中注⼊ 属性解析器 transactionAttributeSource
    		advisor.setTransactionAttributeSource(transactionAttributeSource);
    		// 向事务增强器中注⼊ 事务拦截器 transactionInterceptor
    		advisor.setAdvice(transactionInterceptor);
    		if (this.enableTx != null) {
    			advisor.setOrder(this.enableTx.<Integer>getNumber("order"));
    		}
    		return advisor;
    	}
    
    	@Bean
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	// 属性解析器 transactionAttributeSource
    	public TransactionAttributeSource transactionAttributeSource() {
    		return new AnnotationTransactionAttributeSource();
    	}
    
    	@Bean
    	@Role(BeanDefinition.ROLE_INFRASTRUCTURE)
    	// 事务拦截器 transactionInterceptor
    	public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
    		TransactionInterceptor interceptor = new TransactionInterceptor();
    		interceptor.setTransactionAttributeSource(transactionAttributeSource);
    		if (this.txManager != null) {
    			interceptor.setTransactionManager(this.txManager);
    		}
    		return interceptor;
    	}
    
    }
    

# transactionAttributeSource,属性解析器

AnnotationTransactionAttributeSource属性解析器有⼀个成员变量是annotationParsers,是⼀个集合,可以添加多种注解解析器 (TransactionAnnotationParser):

public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource
		implements Serializable {
	// ......

	private final boolean publicMethodsOnly;
	
  // 注解解析器集合
	private final Set<TransactionAnnotationParser> annotationParsers;
  
}

我们关注 Spring 的注解解析器,部分源码如下:

public class SpringTransactionAnnotationParser implements TransactionAnnotationParser, Serializable {
  
  // ......
  
 	protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
		RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
		// 对应@Transaction属性
		Propagation propagation = attributes.getEnum("propagation");
		rbta.setPropagationBehavior(propagation.value());
		Isolation isolation = attributes.getEnum("isolation");
		rbta.setIsolationLevel(isolation.value());

		rbta.setTimeout(attributes.getNumber("timeout").intValue());
		String timeoutString = attributes.getString("timeoutString");
		Assert.isTrue(!StringUtils.hasText(timeoutString) || rbta.getTimeout() < 0,
				"Specify 'timeout' or 'timeoutString', not both");
		rbta.setTimeoutString(timeoutString);

		rbta.setReadOnly(attributes.getBoolean("readOnly"));
		rbta.setQualifier(attributes.getString("value"));
		rbta.setLabels(Arrays.asList(attributes.getStringArray("label")));

		// ......
		rbta.setRollbackRules(rollbackRules);

		return rbta;
	}

  // ......
}

我看得出来属性解析器的作⽤之⼀就是⽤来解析@Transaction注解。

# transactionInterceptor,事务拦截器

部分源码:

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
 	 	// ......
    public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) {
      setTransactionManager(ptm);
      setTransactionAttributeSource(tas);
    }
  
    public TransactionInterceptor(PlatformTransactionManager ptm, Properties attributes) {
      setTransactionManager(ptm);
      setTransactionAttributes(attributes);
    }
  
  	@Override
    @Nullable
    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, new CoroutinesInvocationCallback() {
        @Override
        @Nullable
        public Object proceedWithInvocation() throws Throwable {
          return invocation.proceed();
        }
        @Override
        public Object getTarget() {
          return invocation.getThis();
        }
        @Override
        public Object[] getArguments() {
          return invocation.getArguments();
        }
      });
    }
    // ......
}

上述组件如何关联起来的?

  • 事务拦截器实现了MethodInterceptor接⼝,追溯⼀下上⾯提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执⾏⽬标⽅法的时候获取其拦截器链,⽽拦截器链就是这个TransactionInterceptor,这就把这两个组件联系起来;
  • 构造⽅法传⼊PlatformTransactionManager(事务管理器)、TransactionAttributeSource(属性解析器),但是追溯⼀下上⾯贴的ProxyTransactionManagementConfiguration的源码, 在注册事务拦截器的时候并没有调⽤这个带参构造⽅法,⽽是调⽤的⽆参构造⽅法,然后再 调⽤set⽅法注⼊这两个属性,效果⼀样。

invokeWithinTransaction ⽅法,部分源码如下:

public abstract class TransactionAspectSupport implements BeanFactoryAware, InitializingBean {
  	// ......
  
  	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 TransactionManager tm = determineTransactionManager(txAttr);

		// ......

		if (txAttr == null || !(ptm instanceof CallbackPreferringPlatformTransactionManager)) {
			// Standard transaction demarcation with getTransaction and commit/rollback calls.
			TransactionInfo txInfo = createTransactionIfNecessary(ptm, 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(获取事务管理器,执行回滚操作)
				completeTransactionAfterThrowing(txInfo, ex);
				throw ex;
			}
			finally {
				cleanupTransactionInfo(txInfo);
			}

			if (retVal != null && vavrPresent && VavrDelegate.isVavrTry(retVal)) {
				// Set rollback-only in case of Vavr failure matching our rollback rules...
				TransactionStatus status = txInfo.getTransactionStatus();
				if (status != null && txAttr != null) {
					retVal = VavrDelegate.evaluateTryFailure(retVal, txAttr, status);
				}
			}
			// 如果目标方法正常运行,则会执行commitTransactionAfterReturning(获取事务管理器,提交事务操作)
			commitTransactionAfterReturning(txInfo);
			return retVal;
		}

		else {
      // ......
    }
	}
  
  // ......
}
上次更新: 12/3/2023, 2:57:06 PM
Spring MVC 简介

Spring MVC 简介→

最近更新
01
2025
01-15
02
Elasticsearch面试题
07-17
03
Elasticsearch进阶
07-16
更多文章>
Theme by Vdoing
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式