Spring的Aop与事务源码分析

Aop原理

1.分析入口@EnableAspectJAutoProxy

1.@EnableAspectJAutoProxy
       @Import(AspectJAutoProxyRegistrar.class):给容器中导入AspectJAutoProxyRegistrar
            利用AspectJAutoProxyRegistrar自定义给容器中注册bean;
            internalAutoProxyCreator=AnnotationAwareAspectJAutoProxyCreator
      给容器中注册一个AnnotationAwareAspectJAutoProxyCreator

2.AnnotationAwareAspectJAutoProxyCreator的作用

2.AnnotationAwareAspectJAutoProxyCreator的作用
    ->AspectJAwareAdvisorAutoProxyCreator
     ->AbstractAdvisorAutoProxyCreator
      ->AbstractAutoProxyCreator
       ->implements SmartInstantiationAwareBeanPostProcessor, BeanFactoryAware
       关注后置处理器(可以在bean初始化前后进行操作),自动装配BeanFactory做了什么事情

3.AbstractAutoProxyCreator.setBeanFactory()

3.AbstractAutoProxyCreator.setBeanFactory()
AbstractAutoProxyCreator.后置处理器逻辑

AbstractAdvisorAutoProxyCreator.setBeanFactory()  -》initBeanFactory
AbstractAdvisorAutoProxyCreator.initBeanFactory()

AnnotationAwareAspectJAutoProxyCreator.initBeanFactory()

在这几个地方打上断点

4.启动容器

4.启动容器
   基本流程
   (1)传入配置类(配置类中传入了internalAutoProxyCreator)
   (2)注册配置类,调用refresh(),刷新容器;
   (3)registerBeanPostProcessors(beanFactory);注册bean的后置处理器来方便拦截bean的创建;
        1)先获取ioc容器已经定义了的需要创建的BeanPostProcessor组件
        2)给容器中加入别的BeanPostProcessor
        3)优先注册实现了PriorityOrdered接口的BeanPostProcessor;
        4)再给容器中注册实现了Ordered接口的BeanPostProcessor;
        5)注册没实现优先级接口的BeanPostProcessor;
        6)注册BeanPostProcessor,实际上就是创建BeanPostProcessor对象,保存在容器中;
            创建internalAutoProxyCreator的BeanPostProcessor【AnnotationAwareAspectJAutoProxyCreator】
               1)创建Bean的实例;
               2)populateBean(beanName, mbd, instanceWrapper);
               3)initializeBean:初始化bean
                      1)invokeAwareMethods():处理Aware接口,让bean对象能感知到容器的存在,从容器中获取一些东西
                      2)applyBeanPostProcessorsBeforeInitialization():应用后置处理器的beanPostProcessorsBeforeInitialization()
                      3)invokeInitMethods():执行自定义的初始化方法
                      4)applyBeanPostProcessorsAfterInitialization():执行后置处理器的beanPostProcessorsAfterInitialization()
               4)BeanPostProcessor(AnnotationAwareAspectJAutoProxyCreator)创建成功:aspectJAutoProxyBuilder
                     

以上为创建和注册AnnotationAwareAspectJAutoProxyCreator的过程

5.执行时机

5.执行时机
AnnotationAwareAspectJAutoProxyCreator -》InstantiationAwareBeanPostProcessor
finishBeanFactoryInitialization(beanFactory);完成单实例bean的创建
   1)遍历获取容器中所有的Bean,依次创建对象getBean(beanName);
       getBean ->doGetBean() ->getSigleton()->
   2)创建bean
       1)先从缓存中获取当前Bean,如果获取到,直接使用;
       只要创建好的bean会被缓存起来
       2)createBean();创建bean
          1)resolveBeforeInstantiation(beanName, mbdToUse);解析BeforeInstantiation,希望后置处理器在此能够返回一个代理对象;如果能返回代理对象就使用,如果不能就继续
                  后置处理器先尝试返回对象;
                  bean = applyBeanPostProcessorsBeforeInstantiation();
                  拿到后置处理器,如果bean是InstantiationAwareBeanPostProcessor则会调用postProcessBeforeInstantiation()方法;

                  如果返回bean不为空,则继续调用applyBeanPostProcessorsAfterInitialization方法
                  if (bean != null) {
                        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
                  }
          2)doCreateBean(beanName, mbdToUse, args);
               1)创建Bean的实例;
               2)populateBean(beanName, mbd, instanceWrapper);
               3)initializeBean:初始化bean
                      1)invokeAwareMethods():处理Aware接口,让bean对象能感知到容器的存在,从容器中获取一些东西
                      2)applyBeanPostProcessorsBeforeInitialization():应用后置处理器的beanPostProcessorsBeforeInitialization()
                      3)invokeInitMethods():执行自定义的初始化方法
                      4)applyBeanPostProcessorsAfterInitialization():执行后置处理器的beanPostProcessorsAfterInitialization()
         

6.创建代理

6.创建代理
    根据上面的分析,会调用到
1)AbstractAutoProxyCreator.postProcessBeforeInstantiation()
    1)判断当前bean是否在advisedBeans中(保存了所有需要增强的bean)
    2)判断当前bean是否是基础类型的Advice,Pointcut,Advisor,AopInfrastructureBean或者是否是切面(@Aspect)
    3)是否需要跳过
        1)获取候选增强器(切面里面的通知方法)【List<Advisor> candidateAdvisors】
             每一个封装的通知方法的增强器是InstantianModelAwarePointAdvisor;
             判断每一个增强器是否是AspectJPointcutAdvisor类型的;返回true
        2)永远返回false

2)创建对象
AbstractAutoProxyCreator.postProcessorsAfterInitialization();
     return wrapIfNecessary(bean, beanName, cacheKey);包装如果有需要的情况下
     1)获取当前bean的所有增强方法(即我们的通知方法,before,after等等) Obejct[] specifcInterceptors
         1)找到候选的所有增强器(找哪些通知方法是需要切入当前bean方法的)
         2)获取到能在bean使用的增强器.
         3)给增强器排序
     2)保存当前bean在advisedBeans中;
     3)如果当前bean需要增强,则创建当前bean代理对象
         1)获取所有增强器(通知方法)
         2)保存到proxyFactory
         3)创建代理对象
            JdkDynamicAopProxy(AdvisedSupport config);jdk动态代理
            CglibAopProxy(AdvisedSupport config);cglib动态代理
     4)返回代理对象
     5)以后容器中获取到的就是这个组件的代理对象,执行目标方法的时候,代理对象就会执行通知方法的流程.


AbstractAutoProxyCreator.postProcessorsAfterInitialization();代码如下


public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
        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;
    }

postProcessorsAfterInitialization()代码如下

public Object postProcessAfterInitialization(@Nullable Object bean, String beanName) throws BeansException {
        if (bean != null) {
            Object cacheKey = getCacheKey(bean.getClass(), beanName);
            if (!this.earlyProxyReferences.contains(cacheKey)) {
                return wrapIfNecessary(bean, beanName, cacheKey);
            }
        }
        return bean;
    }

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

调用了createProxy()
最终会调用到
DefaultAopProxyFactory.createAopProxy(AdvisedSupport config)

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);
            }
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            return new JdkDynamicAopProxy(config);
        }
    }

即如果实现了接口则用jdk动态代理,当然也可以通过配置参数Optimize=true 或ProxyTargetClass="cglib"来使用cglib动态代理


7.获取拦截器链MethodInterceptor

目标方法执行;
    容器中保存了组件的代理对象(cglib增强后的对象),这个对象里保存了详细信息(比如增强器,目标对象,xxx);
      1)CglibAopProxy.intercept();拦截目标方法的执行;
      2)根据ProxyFactory对象获取将要执行的目标方法拦截器链;
          List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
          1)List<Object> interceptorList 保存所有拦截器5
                一个默认的ExposeInvocationInterceptor和4个增强器
          2)遍历所有的增强器,将其转为Interceptor;
              registry.getInterceptors(advisor);
          3)将增强器转为List<MethodInterceptor>;
             如果是MethodInterceptor,直接加入到集合中
             如果不是,使用AdvisorAdaptor将增强器转为MethodInterceptor;   
             转换完成返回MethodInterceptor数组;

      3)如果没有拦截器链,直接执行目标方法;
           拦截器链(每一个方法又被包装为方法拦截器,利用MethodInterceptor机制)
      4)如果有拦截器链,把需要执行的目标对象,目标方法,拦截器等信息传入
        创建一个CglibMethodInvocation对象,并调用Object retVal =mi.proceed();
      5)拦截器链的触发过程
         1)

8.拦截器链的触发过程

mi.proceed()的执行
15854876-a05bf3b0b3149559.png
Aop执行过程.png

org.springframework.aop.framework.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();
        }

事务原理

1.@EnableTransactionManagement
       利用TransactionManagementConfigurationSelector给容器中导入了两个组件
       AutoProxyRegistrar
       ProxyTransactionManagementConfiguration

2.AutoProxyRegistrar
    给容器中注册一个InfrastructureAdvisorAutoProxyCreator组件;
    InfrastructureAdvisorAutoProxyCreator的作用
    就是利用后置处理器机制在对象创建以后,包装对象,返回一个代理对象(增强器),代理对象执行方法利用拦截器链进行处理

3.ProxyTransactionManagementConfiguration
     1.给容器中注册事务增强器
       (1)事务增强器需要的事务注解信息,AnnotationTransactionAttributeSource解析事务
       (2)事务拦截器
           TransactionInterceptor;保存了事务属性信息,事务管理器;
           同时它是一个MethodInterceptor;
               在目标方法执行的时候;
                   执行拦截器链;
                   事务拦截器:
                       ①先获取事务相关属性
                       ②再获取PlatformTranactionManager,如果没有先添加指定任何PlatformTranactionManager,最终会从容器中按照类型获取一个PlatformTranactionManager
                       ③执行目标方法
                           如果异常,获取到事务管理器,利用事务管理器回滚操作;
                           如果正常,利用事务提交,进行提交

整个调用链条如下

org.springframework.transaction.interceptor.TransactionInterceptor.invoke
  ->org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction  
   ->org.springframework.transaction.interceptor.TransactionAspectSupport.getTransactionAttributeSource  获取事务相关属性
   ->org.springframework.transaction.interceptor.TransactionAspectSupport.determineTransactionManager  再获取PlatformTranactionManager
   ->org.springframework.transaction.interceptor.TransactionAspectSupport.createTransactionIfNecessary   
    ->org.springframework.transaction.support.AbstractPlatformTransactionManager.getTransaction  事务的传播属性就是在这个方法里面判断的 
     ->org.springframework.jca.cci.connection.CciLocalTransactionManager.doBegin   获取底层数据库连接
   ->org.springframework.transaction.interceptor.TransactionAspectSupport.InvocationCallback.proceedWithInvocation  执行目标方法
   ->org.springframework.transaction.interceptor.TransactionAspectSupport#completeTransactionAfterThrowing 异常则回滚事务
   ->org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning  成功则提交事务 

代码如下

public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {
.....
}

invoke()方法

public Object invoke(final 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()方法

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);
                再获取PlatformTranactionManager
        final PlatformTransactionManager tm = determineTransactionManager(txAttr);

        final String joinpointIdentification = methodIdentification(method, targetClass, txAttr);
                
                if是声明式事务,else是编程式事务
        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
                                 rollback回滚事务
                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;
            }
        }
    }

getTransaction()方法

public final TransactionStatus getTransaction(@Nullable TransactionDefinition definition) throws TransactionException {
        Object transaction = doGetTransaction();

        // Cache debug flag to avoid repeated checks.
        boolean debugEnabled = logger.isDebugEnabled();

        if (definition == null) {
            // Use defaults if no transaction definition given.
            definition = new DefaultTransactionDefinition();
        }

        if (isExistingTransaction(transaction)) {
            // Existing transaction found -> check propagation behavior to find out how to behave.
            return handleExistingTransaction(definition, transaction, debugEnabled);
        }

        // Check definition settings for new transaction.
        if (definition.getTimeout() < TransactionDefinition.TIMEOUT_DEFAULT) {
            throw new InvalidTimeoutException("Invalid transaction timeout", definition.getTimeout());
        }

        // No existing transaction found -> check propagation behavior to find out how to proceed.
        if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_MANDATORY) {
            throw new IllegalTransactionStateException(
                    "No existing transaction found for transaction marked with propagation 'mandatory'");
        }
        else if (definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRED ||
                definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_REQUIRES_NEW ||
                definition.getPropagationBehavior() == TransactionDefinition.PROPAGATION_NESTED) {
            SuspendedResourcesHolder suspendedResources = suspend(null);
            if (debugEnabled) {
                logger.debug("Creating new transaction with name [" + definition.getName() + "]: " + definition);
            }
            try {
                boolean newSynchronization = (getTransactionSynchronization() != SYNCHRONIZATION_NEVER);
                DefaultTransactionStatus status = newTransactionStatus(
                        definition, transaction, true, newSynchronization, debugEnabled, suspendedResources);
                doBegin(transaction, definition);
                prepareSynchronization(status, definition);
                return status;
            }
            catch (RuntimeException | Error ex) {
                resume(null, suspendedResources);
                throw ex;
            }
        }
        else {
            // Create "empty" transaction: no actual transaction, but potentially synchronization.
            if (definition.getIsolationLevel() != TransactionDefinition.ISOLATION_DEFAULT && logger.isWarnEnabled()) {
                logger.warn("Custom isolation level specified but no actual transaction initiated; " +
                        "isolation level will effectively be ignored: " + definition);
            }
            boolean newSynchronization = (getTransactionSynchronization() == SYNCHRONIZATION_ALWAYS);
            return prepareTransactionStatus(definition, null, true, newSynchronization, debugEnabled, null);
        }
    }

doBegin()方法

protected void doBegin(Object transaction, TransactionDefinition definition) {
        CciLocalTransactionObject txObject = (CciLocalTransactionObject) transaction;
        ConnectionFactory connectionFactory = obtainConnectionFactory();
        Connection con = null;

        try {
            con = connectionFactory.getConnection();
            if (logger.isDebugEnabled()) {
                logger.debug("Acquired Connection [" + con + "] for local CCI transaction");
            }

            ConnectionHolder connectionHolder = new ConnectionHolder(con);
            connectionHolder.setSynchronizedWithTransaction(true);

            con.getLocalTransaction().begin();
            int timeout = determineTimeout(definition);
            if (timeout != TransactionDefinition.TIMEOUT_DEFAULT) {
                connectionHolder.setTimeoutInSeconds(timeout);
            }

            txObject.setConnectionHolder(connectionHolder);
            TransactionSynchronizationManager.bindResource(connectionFactory, connectionHolder);
        }
        catch (NotSupportedException ex) {
            ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
            throw new CannotCreateTransactionException("CCI Connection does not support local transactions", ex);
        }
        catch (LocalTransactionException ex) {
            ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
            throw new CannotCreateTransactionException("Could not begin local CCI transaction", ex);
        }
        catch (Throwable ex) {
            ConnectionFactoryUtils.releaseConnection(con, connectionFactory);
            throw new TransactionSystemException("Unexpected failure on begin of CCI local transaction", ex);
        }
    }

猜你喜欢

转载自blog.csdn.net/weixin_34130269/article/details/87165523