Spring 系列(九)AOP源码剖析

第1节 代理对象创建

PS: 查看源码的jar版本为 Spring-beans:5.2.15.release

1.1 AOP基础用例准备

Bean定义

@Component
public class LagouBean {
 public void tech(){
 System.out.println("java learning......");
 }
}

Aspect定义

package com.lagou;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.stereotype.Component;
@Component
@Aspect
public class LagouAspect {
 @Pointcut("execution(* com.lagou.*.*(..))")
 public void pointcut(){
 }
 @Before("pointcut()")
 public void before() {
 System.out.println("before method ......");
 }
}

测试用例

/**
* 测试⽤例:Aop 代理对象创建
*/
@Test
public void testAopProxyBuild(){
 ApplicationContext applicationContext = new AnnotationConfigApplicationContext(SpringConfig.class);
 LagouBean lagouBean = applicationContext.getBean(LagouBean.class);
 lagouBean.tech();
}

1.2 时机点分析


我们发现在getBean之前,LagouBean 对象已经产生(即在第一行初始化代码中完成),而且该对象是一个代理对象(Cglib代理对象),我们断定,容器初始化过程中目标bean已经完成了代理,返回代理对象。

1.3 代理对象创建流程

AbstractAutowireCapableBeanFactory#initializeBean

/**
* 初始化Bean
* 包括Bean的后置处理器初始化
* Bean的一些初始化方法的执行init-method
* Bean的实现声明周期相关接口的属性注入
*/
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
// 执行所有的AwareMethods
        if (System.getSecurityManager() != null) {
            AccessController.doPrivileged((PrivilegedAction) () -> {
                invokeAwareMethods(beanName, bean);
                return null;
            }, getAccessControlContext());
        }
        else {
            invokeAwareMethods(beanName, bean);
        }

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

        try {
//这里就开始执行afterPropertiesSet(实现了InitializingBean接口)方法和initMethod
            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()) {
//整个Bean初始化完成,执行后置处理器方法
            wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
        }

        return wrappedBean;
    }

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization

    @Override
    public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
            throws BeansException {

        Object result = existingBean;
//循环执行后置处理器
        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 = this.getCacheKey(bean.getClass(), beanName);
            if (this.earlyProxyReferences.remove(cacheKey) != bean) {
                return this.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;
        } else if (Boolean.FALSE.equals(this.advisedBeans.get(cacheKey))) {
            return bean;
        } else if (!this.isInfrastructureClass(bean.getClass()) && !this.shouldSkip(bean.getClass(), beanName)) {
//得到所有候选的Advisor,对Advisors的bean的方法双层遍历匹配。最终得到List,即specificInterceptors
            Object[] specificInterceptors = this.getAdvicesAndAdvisorsForBean(bean.getClass(), beanName, (TargetSource)null);
            if (specificInterceptors != DO_NOT_PROXY) {
                this.advisedBeans.put(cacheKey, Boolean.TRUE);
//重点,创建代理对象
                Object proxy = this.createProxy(bean.getClass(), beanName, specificInterceptors, new SingletonTargetSource(bean));
                this.proxyTypes.put(cacheKey, proxy.getClass());
                return proxy;
            } else {
                this.advisedBeans.put(cacheKey, Boolean.FALSE);
                return bean;
            }
        } else {
            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(强制cglib代理方式)
        if (!proxyFactory.isProxyTargetClass()) {
            if (this.shouldProxyTargetClass(beanClass, beanName)) {
                proxyFactory.setProxyTargetClass(true);
            } else {
                this.evaluateProxyInterfaces(beanClass, proxyFactory);
            }
        }
//把指定和通用拦截对象合并,并都是适配成Advisor
        Advisor[] advisors = this.buildAdvisors(beanName, specificInterceptors);
        proxyFactory.addAdvisors(advisors);
//设置参数
        proxyFactory.setTargetSource(targetSource);
        this.customizeProxyFactory(proxyFactory);
        proxyFactory.setFrozen(this.freezeProxy);
        if (this.advisorsPreFiltered()) {
            proxyFactory.setPreFiltered(true);
        }
//上面准备昨晚就开始创建代理
        return proxyFactory.getProxy(this.getProxyClassLoader());
    }

接下来跟进到ProxyFactory中

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

ProxyCreatorSupport

//省略了一些代码
public class ProxyCreatorSupport extends AdvisedSupport {
    private AopProxyFactory aopProxyFactory;
    public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }
    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            this.activate();
        }
//先获取创建AopProxy的工厂,在由此创建AopProxy
        return this.getAopProxyFactory().createAopProxy(this);
    }
    public AopProxyFactory getAopProxyFactory() {
        return this.aopProxyFactory;
    }
}

流程就是用AopProxyFactory创建AopProxy,再用AopProxy创建代理对象,这里的AopProxyFactory默认是DefaultAopProxyFactory,看它的createAopProxy方法。
DefaultAopProxyFactory#createAopProxy

    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        if (!config.isOptimize() && !config.isProxyTargetClass() && !this.hasNoUserSuppliedProxyInterfaces(config)) {
            return new JdkDynamicAopProxy(config);
        } else {
            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.");
            } else {
                return (AopProxy)(!targetClass.isInterface() && !Proxy.isProxyClass(targetClass) ? new ObjenesisCglibAopProxy(config) : new JdkDynamicAopProxy(config));
            }
        }
    }

DefaultAopProxyFactory#hasNoUserSuppliedProxyInterfaces

    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        Class[] ifcs = config.getProxiedInterfaces();
        return ifcs.length == 0 || ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0]);
    }

这里决定创建代理对象用的是JDK Proxy,还是用Cglib了。最简单的从使用方面使用来说:设置proxyTargetClass=true强制使用cglib,什么参数都不设置并且对象类实现了接口则默认用JDK代理,如果没有实现接口则也必须使用cglib。
ProxyFactory#getProxy(java.lang.ClassLoader)
---->CglibAopProxy#getProxy (找到CglibAopProxy作为实现类查看源码)

    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;
            int x;
            if (rootClass.getName().contains("$$")) {
                proxySuperClass = rootClass.getSuperclass();
                Class[] additionalInterfaces = rootClass.getInterfaces();
                Class[] var5 = additionalInterfaces;
                int var6 = additionalInterfaces.length;

                for(x = 0; x < var6; ++x) {
                    Class additionalInterface = var5[x];
                    this.advised.addInterface(additionalInterface);
                }
            }

            this.validateClassIfNecessary(proxySuperClass, classLoader);
//配置 Cglib 增强
            Enhancer enhancer = this.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 = this.getCallbacks(rootClass);
            Class[] types = new Class[callbacks.length];

            for(x = 0; x < types.length; ++x) {
                types[x] = callbacks[x].getClass();
            }

            enhancer.setCallbackFilter(new CglibAopProxy.ProxyCallbackFilter(this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            enhancer.setCallbackTypes(types);
//生成代理类。并且创建一个代理类的实例
            return this.createProxyClassAndInstance(enhancer, callbacks);
        } catch (IllegalArgumentException | CodeGenerationException var9) {
            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", var9);
        } catch (Throwable var10) {
            throw new AopConfigException("Unexpected AOP exception", var10);
        }
    }

AOP源码分析方法调用关系记录

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean
调⽤
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
调用
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#postProcessAfterInitialization(后置处理器AbstractAutoProxyCreator完成bean代理对象创建)
调⽤
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#wrapIfNecessary
调⽤
org.springframework.aop.framework.autoproxy.AbstractAutoProxyCreator#createProxy (在这⼀步把委托对象的aop增强和通用拦截进行合并,最终给代理对象)
调⽤
org.springframework.aop.framework.DefaultAopProxyFactory#createAopProxy
调⽤
org.springframework.aop.framework.CglibAopProxy#getProxy(java.lang.ClassLoader
)

第2节 声明型事务

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

2.1 EnableTransactionManagement

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

@EnableTransactionManagement 注解使用@import引入了TransactionManagementConfigurationSelector类,这个类又向容器导入了两个重要的组件。


2.2 加载事务控制组件

  • AutoProxyRegistrar
    AutoProxyRegistrar类的registerBeanDefinitions方法中又注册一个组件



    AopConfigUtils#registerAutoProxyCreatorIfNecessary

    @Nullable
    public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry) {
        return registerAutoProxyCreatorIfNecessary(registry, (Object)null);
    }

    @Nullable
    public static BeanDefinition registerAutoProxyCreatorIfNecessary(BeanDefinitionRegistry registry, @Nullable Object source) {
        return registerOrEscalateApcAsRequired(InfrastructureAdvisorAutoProxyCreator.class, registry, source);
    }

发现最终,注册了一个叫做InfrastructureAdvisorAutoProxyCreator的bean,而这个类是AbstractAutoProxyCreator的子类,实现了SmartInstantiationAwareBeanPostProcessor接口

继承体系结构图如下



它实现了SmartInstantiationAwareBeanPostProcessor,说明是一个后置处理器,而Spring AOP开启的@EnableAspectJAutoProxy时注册的AnnotationAwareAspectJProxyCreator实现的是同一个接口,所以,声明型事是Spring AOP思想的一种应用。

  • ProxyTransactionManagementConfiguration组件
@Configuration(
    proxyBeanMethods = false
)
@Role(2)
public class ProxyTransactionManagementConfiguration extends AbstractTransactionManagementConfiguration {
    public ProxyTransactionManagementConfiguration() {
    }

    @Bean(
        name = {"org.springframework.transaction.config.internalTransactionAdvisor"}
    )
    @Role(2)
    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((Integer)this.enableTx.getNumber("order"));
        }

        return advisor;
    }

    @Bean
    @Role(2)
//属性解析器 transactionAttributeSource
    public TransactionAttributeSource transactionAttributeSource() {
        return new AnnotationTransactionAttributeSource();
    }

    @Bean
    @Role(2)
//事务拦截器 transactionInterceptor
    public TransactionInterceptor transactionInterceptor(TransactionAttributeSource transactionAttributeSource) {
        TransactionInterceptor interceptor = new TransactionInterceptor();
        interceptor.setTransactionAttributeSource(transactionAttributeSource);
        if (this.txManager != null) {
            interceptor.setTransactionManager(this.txManager);
        }

        return interceptor;
    }
}

ProxyTransactionManagementConfiguration是一个容器配置类,注册了一个组件transactionAdvisor,称为事务增强器,然后在这个事务增强器中又注入了两个属性:transactionAttributeSource(属性解析器)、transactionInterceptor(事务拦截器)。

  1. 属性解析器 AnnotationTransactionAttributeSource 部分源码
public class AnnotationTransactionAttributeSource extends AbstractFallbackTransactionAttributeSource implements Serializable {
    private static final boolean jta12Present;
    private static final boolean ejb3Present;
    static {
        ClassLoader classLoader = AnnotationTransactionAttributeSource.class.getClassLoader();
        jta12Present = ClassUtils.isPresent("javax.transaction.Transactional", classLoader);
        ejb3Present = ClassUtils.isPresent("javax.ejb.TransactionAttribute", classLoader);
    }
    private final boolean publicMethodsOnly;
//注解解析器集合
    private final Set annotationParsers;

属性解析器中有个成员变量annotationParsers,是一个集合,可以添加多个注解解析器(TransactionAnnotationParser),我们关注Spring的注解解析器,部分源码如下。
SpringTransactionAnnotationParser#parseTransactionAnnotation

    protected TransactionAttribute parseTransactionAnnotation(AnnotationAttributes attributes) {
        RuleBasedTransactionAttribute rbta = new RuleBasedTransactionAttribute();
        Propagation propagation = (Propagation)attributes.getEnum("propagation");
        rbta.setPropagationBehavior(propagation.value());
        Isolation isolation = (Isolation)attributes.getEnum("isolation");
        rbta.setIsolationLevel(isolation.value());
        rbta.setTimeout(attributes.getNumber("timeout").intValue());
        rbta.setReadOnly(attributes.getBoolean("readOnly"));
        rbta.setQualifier(attributes.getString("value"));
        List rollbackRules = new ArrayList();
        Class[] var6 = attributes.getClassArray("rollbackFor");

解析的属性名对应@Transactional的属性,属性解析器作用之一就是用解析@Transaction注解

  1. transactionInterceptor事务拦截器,部分源码如下
public class TransactionInterceptor extends TransactionAspectSupport implements MethodInterceptor, Serializable {

//构造方法传入
    public TransactionInterceptor(TransactionManager ptm, TransactionAttributeSource tas) {
        this.setTransactionManager(ptm);
        this.setTransactionAttributeSource(tas);
    }
    @Nullable
    public Object invoke(MethodInvocation invocation) throws Throwable {
        Class targetClass = invocation.getThis() != null ? AopUtils.getTargetClass(invocation.getThis()) : null;
        Method var10001 = invocation.getMethod();
        invocation.getClass();
//添加事务支持
        return this.invokeWithinTransaction(var10001, targetClass, invocation::proceed);
    }
}
  • 上述注解如何关联起来?
    • 事务拦截器实现了MethodInterceptor接口,追溯一下上面提到的InfrastructureAdvisorAutoProxyCreator后置处理器,它会在代理对象执行目标方法的时候获取其拦截器链,而拦截器链就是这个TransactionInterceptor,这就把两个组件联系起来。
    • ProxyTransactionManagementConfiguration构造方法传入PlatformTransactionManager(事务管理器)(TransactionManager的子类)、TransactionAttributeSource (属性解析器)但是追溯一下上面贴的ProxyTransactionManagementConfiguration源码,在注册事务拦截器的时候并没有调用这个带参构造方法,而是调用无参构造方法,然后再通过set方法注入这两个属性效果一样。
  • invokeWithinTransaction 方法,部分源码如下
    protected Object invokeWithinTransaction(Method method, @Nullable Class targetClass, TransactionAspectSupport.InvocationCallback invocation) throws Throwable {
//获取属性解析器,即在ProxyTransactionManagementConfiguration容器配置类中注册事务拦截器时注入的
        TransactionAttributeSource tas = this.getTransactionAttributeSource();
        TransactionAttribute txAttr = tas != null ? tas.getTransactionAttribute(method, targetClass) : null;
//获取事务管理器
        TransactionManager tm = this.determineTransactionManager(txAttr);
        String joinpointIdentification = this.methodIdentification(method, targetClass, txAttr);
                try {
                    retVal = invocation.proceedWithInvocation();
                      }catch{
//如果目标方法抛异常,会执行completeTransactionAfterThrowing(获取事务管理器,执行回滚操作)
                    this.completeTransactionAfterThrowing(txInfo, var18);
                    throw var18;
                } finally {
                    this.cleanupTransactionInfo(txInfo);
                }
//如果目标方法正常进行,则会执行commitTransactionAfterReturning(获取事务管理器,执行提交事务操作)
                this.commitTransactionAfterReturning(txInfo);
                return retVal;
}

声明型事务分析记录
@EnableTransactionManagement注解

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

你可能感兴趣的:(Spring 系列(九)AOP源码剖析)