Java Spring

注册后置处理器开启对事务的支持

@EnableTransactionManagement

@EnableTransactionManagement注解的主要作用是开启对事务的支持,源码如下:

  1. @Target(ElementType.TYPE)
  2. @Retention(RetentionPolicy.RUNTIME)
  3. @Documented
  4. @Import(TransactionManagementConfigurationSelector.class)
  5. public @interface EnableTransactionManagement {
  6. boolean proxyTargetClass() default false;
  7. AdviceMode mode() default AdviceMode.PROXY;
  8. int order() default Ordered.LOWEST_PRECEDENCE;
  9. }

这里最核心的是TransactionManagementConfigurationSelector类,这个类主要的作用是通过ImportSelector注册了AutoProxyRegistrarProxyTransactionManagementConfiguration2个组件,源码如下:

  1. public class TransactionManagementConfigurationSelector extends AdviceModeImportSelector<EnableTransactionManagement> {
  2. @Override
  3. protected String[] selectImports(AdviceMode adviceMode) {
  4. switch (adviceMode) {
  5. case PROXY:
  6. // 注册 InfrastructureAdvisorAutoProxyCreator 后置处理器和事务管理器组件
  7. return new String[] {AutoProxyRegistrar.class.getName(), ProxyTransactionManagementConfiguration.class.getName()};
  8. case ASPECTJ:
  9. return new String[] {TransactionManagementConfigUtils.TRANSACTION_ASPECT_CONFIGURATION_CLASS_NAME};
  10. default:
  11. return null;
  12. }
  13. }
  14. }

AutoProxyRegistrar

AutoProxyRegistrar 的主要作用是将InfrastructureAdvisorAutoProxyCreator后置处理器注册到容器,注册这个后置处理器和Spring AOP注册AnnotationAwareAspectJAutoProxyCreator后置处理器一样,这里就不在重复说明了。InfrastructureAdvisorAutoProxyCreator 他是实现了BeanPostProcessor 接口的后置处理器,所以所有 Bean 的初始化都会调用其 postProcessAfterInitialization 方法,这个方法的实现是在其父类AbstractAutoProxyCreator类中。

ProxyTransactionManagementConfiguration

通过ProxyTransactionManagementConfiguration来注册事务管理器组件,这个类本身也是一个配置类。在这个配置类中将会注册一下三个组件:

  • BeanFactoryTransactionAttributeSourceAdvisor:事务增强器,包含了切面组件 TransactionInterceptor和标签解析器TransactionAttributeSource
  • TransactionAttributeSource@Transaction注解标签解析器
  • TransactionInterceptor:保存了事务属性信息,事务管理器;它本身也是一个方法拦截器,在invoke方法中进行了事务的处理。

    创建代理Bean

    上面说了所以所有 Bean 的初始化都会调用其 AbstractAutoProxyCreator#postProcessAfterInitialization 方法来完成Bean的增强,跟进去可以看到这段代码:

    1. @Override
    2. public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
    3. if (bean != null) {
    4. Object cacheKey = getCacheKey(bean.getClass(), beanName);
    5. if (!this.earlyProxyReferences.contains(cacheKey)) {
    6. return wrapIfNecessary(bean, beanName, cacheKey);
    7. }
    8. }
    9. return bean;
    10. }

    可以看到生代理对象是在wrapIfNecessary(bean, beanName, cacheKey);方法中完成的,源码如下:

    1. protected Object wrapIfNecessary(Object bean, String beanName, Object cacheKey) {
    2. // 如果存在建言那么久创建代理类
    3. // 获取拦截链
    4. Object[] specificInterceptors = getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, null);
    5. if (specificInterceptors != DO_NOT_PROXY) {
    6. this.advisedBeans.put(cacheKey, Boolean.TRUE);
    7. // 使用拦截链创建代理对象,对原有的Bean进行增强
    8. Object proxy = createProxy(
    9. bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
    10. this.proxyTypes.put(cacheKey, proxy.getClass());
    11. return proxy;
    12. }
    13. this.advisedBeans.put(cacheKey, Boolean.FALSE);
    14. return bean;
    15. }

    找到拦截链的的核心方法是 BeanFactoryAdvisorRetrievalHelper#findAdvisorBeans方法

    1. findAdvisorBeans:67, BeanFactoryAdvisorRetrievalHelper (org.springframework.aop.framework.autoproxy)
    2. findCandidateAdvisors:102, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
    3. findEligibleAdvisors:88, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
    4. getAdvicesAndAdvisorsForBean:70, AbstractAdvisorAutoProxyCreator (org.springframework.aop.framework.autoproxy)
    5. wrapIfNecessary:346, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
    6. postProcessAfterInitialization:298, AbstractAutoProxyCreator (org.springframework.aop.framework.autoproxy)
    7. applyBeanPostProcessorsAfterInitialization:423, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
    8. initializeBean:1638, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
    9. doCreateBean:555, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
    10. createBean:483, AbstractAutowireCapableBeanFactory (org.springframework.beans.factory.support)
    11. getObject:312, AbstractBeanFactory$1 (org.springframework.beans.factory.support)
    12. getSingleton:230, DefaultSingletonBeanRegistry (org.springframework.beans.factory.support)
    13. doGetBean:308, AbstractBeanFactory (org.springframework.beans.factory.support)
    14. getBean:197, AbstractBeanFactory (org.springframework.beans.factory.support)
    15. preInstantiateSingletons:761, DefaultListableBeanFactory (org.springframework.beans.factory.support)
    16. finishBeanFactoryInitialization:867, AbstractApplicationContext (org.springframework.context.support)
    17. refresh:543, AbstractApplicationContext (org.springframework.context.support)
    18. <init>:84, AnnotationConfigApplicationContext (org.springframework.context.annotation)

    源码如下:

    1. public List<Advisor> findAdvisorBeans() {
    2. // Determine list of advisor bean names, if not cached already.
    3. String[] advisorNames = null;
    4. synchronized (this) {
    5. advisorNames = this.cachedAdvisorBeanNames;
    6. if (advisorNames == null) {
    7. // 获取所有增强器的名称
    8. advisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(
    9. this.beanFactory, Advisor.class, true, false);
    10. this.cachedAdvisorBeanNames = advisorNames;
    11. }
    12. }
    13. if (advisorNames.length == 0) {
    14. return new LinkedList<Advisor>();
    15. }
    16. List<Advisor> advisors = new LinkedList<Advisor>();
    17. for (String name : advisorNames) {
    18. if (isEligibleBean(name)) {
    19. if (this.beanFactory.isCurrentlyInCreation(name)) {
    20. if (logger.isDebugEnabled()) {
    21. logger.debug("Skipping currently created advisor '" + name + "'");
    22. }
    23. }
    24. else {
    25. try {
    26. // 根据名称增强器
    27. advisors.add(this.beanFactory.getBean(name, Advisor.class));
    28. }
    29. ...
    30. }
    31. }
    32. }
    33. // 返回拦截链
    34. return advisors;
    35. }

    创建代理Bean的核心流程:

  1. 单例Bean初始化完成后执行后置处理器 AbstractAutoProxyCreator#postProcessAfterInitialization 方法
  2. 在容器中找Advisor类型的所有增强器名称,这就会将与事务相关的增强器BeanFactoryTransactionAttributeSourceAdvisor找出来
  3. 根据增强器名称获取对应的实例,并生成拦截链
  4. 判断代理类型
  5. 根据不同的代理类型和拦截链创建代理对象

    执行业务方法进行拦截

    前面AOP说过不管理是JdkDynamicAopProxy还是CglibAopProxy代理,他们的执行最终都会去调用MethodInterceptor.invoke()方法,而事务对应的方法拦截器是TransactionInterceptor类。也就是说对事务的增强起始是在TransactionInterceptorinvoke方法中。源码如下:

    1. @Override
    2. public Object invoke(final MethodInvocation invocation) throws Throwable {
    3. ...
    4. return invokeWithinTransaction(invocation.getMethod(), targetClass, new InvocationCallback() {
    5. @Override
    6. public Object proceedWithInvocation() throws Throwable {
    7. return invocation.proceed();
    8. }
    9. });
    10. }
    11. protected Object invokeWithinTransaction(Method method, Class<?> targetClass, final InvocationCallback invocation)
    12. throws Throwable {
    13. // 获取事务属性
    14. final TransactionAttribute txAttr = getTransactionAttributeSource().getTransactionAttribute(method, targetClass);
    15. // 获取事务管理器
    16. final PlatformTransactionManager tm = determineTransactionManager(txAttr);
    17. // 构造方法唯一标示
    18. final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
    19. // 声明式事务
    20. if (txAttr == null || !(tm instanceof CallbackPreferringPlatformTransactionManager)) {
    21. // 创建事务
    22. TransactionInfo txInfo = createTransactionIfNecessary(tm, txAttr, joinpointIdentification);
    23. Object retVal = null;
    24. try {
    25. // 执行被增强的方法
    26. retVal = invocation.proceedWithInvocation();
    27. }
    28. catch (Throwable ex) {
    29. // 异常回滚
    30. completeTransactionAfterThrowing(txInfo, ex);
    31. throw ex;
    32. }
    33. finally {
    34. // 清除信息
    35. cleanupTransactionInfo(txInfo);
    36. }
    37. // 提交事务
    38. commitTransactionAfterReturning(txInfo);
    39. return retVal;
    40. }
    41. // 编程式事务
    42. ...
    43. }

    从上面的源码可以看出,一个事务处理的标准流程:

  6. createTransactionIfNecessary 创建一个事务

  7. invocation.proceedWithInvocation(); 执行业务方法
  8. completeTransactionAfterThrowing(txInfo, ex); 如果遇到异常,事务回滚
  9. commitTransactionAfterReturning(txInfo); 如果没有异常就提交事务

在创建,回滚和提交事务方法中还有的很多对嵌套事务的逻辑,比如事务的传递性,事务回滚的条件判断等。