Spring AOP源码解读

目录

一、概述

二、SpringAOP运行时增强

三、Spring AOP的常用类

四、Spring AOP源码分析

1.XML 配置

2.ProxyFactoryBean生成AOP代理对象

3.具体的两种代理对象生成源码

1、 JDK动态代理:

2、CGLIB动态代理

五、切点和切面分析

六、参考


一、概述

  1. AOP(Aspect Orient Programming):面向切面编程;
    用途:用于系统中的横切关注点,比如日志管理,事务管理;
    实现:利用代理模式,通过代理对象对被代理的对象增加功能。所以,关键在于AOP框架自动创建AOP代理对象,代理模式分为静态代理和动态代理;
    框架
    AspectJ使用静态代理,编译时增强,在编译期生成代理对象;
    SpringAOP使用动态代理,运行时增强,在运行时,动态生成代理对象;
  2. AspectJ框架;
    经过AspectJ的编译器编译后的java字节码,会比java源码多一些代码,即在编译阶段,将定义的Aspect切面织入Java字节码中,运行时就是已经被增强过的类了;支持到方法、字段,构造器级别
  3. SpringAOP框架;
    区别于AspectJ,Spring AOP使用的是动态代理,不修改字节码,而是运行时在内存中临时创建一个AOP代理对象,AOP对象包含了被代理对象的全部方法,并在特定的切点做了增强处理,回调被代理对象的方法;支持到方法级别

二、SpringAOP运行时增强

Spring AOP动态代理主要是两种方式,JDK动态代理和CGLIB动态代理。

  • JDK动态代理:通过反射来接收被代理的类,并且被代理的类必须实现接口;
    核心是:java.lang.reflect.InvocationHandler接口 与 java.lang.reflect.Proxy类;
  • CGLIB动态代理:目标类没有实现接口,Spring AOP会选择使用CGLIB在运行时动态的生成某个类的子类,因此,CGLIB是通过继承的方式,用子类实现对目标类的增强,final class不可继承的类,无法使用CGLIB做动态代理。
  • Spring的AOP与IOC:Spring AOP对象由Spring IOC容器自动生成、管理,其依赖关系也由IOC容器负责管理,那么AOP对象可以直接使用容器中的其他Bean实例作为被代理对象,所以此时使用SpringAOP只需要定义切点(pointcut)和 增强(advice)即可。
  • AOP代理的方法通过在目标对象的切入点动态的织入增强处理,完成对目标方法的增强。

三、Spring AOP的常用类

Spring AOP源码解读_第1张图片 ProxyConfig类的继承结构
  • ProxyConfig类:所有Spring AOP生成的代理对象的基类,主要为其AOP代理对象工厂实现类提供配置属性。
public class ProxyConfig implements Serializable {

    private boolean proxyTargetClass = false;
    private boolean optimize = false;
    boolean opaque = false;
    boolean exposeProxy = false;
    private boolean frozen = false;

    public void copyFrom(ProxyConfig other) {
        Assert.notNull(other, "Other ProxyConfig object must not be null");
        this.proxyTargetClass = other.proxyTargetClass;
        this.optimize = other.optimize;
        this.exposeProxy = other.exposeProxy;
        this.frozen = other.frozen;
        this.opaque = other.opaque;
    }
}
  • AdvisedSupport类:ProxyConfig类的子类,封装了AOP中通用的对增强(Advice)和通知器(Advisor)的相关操作,对于所有生成AOP代理对象都通用,而代理对象的生成由子类完成;
  • ProxyCreatorSupport类:AdvisedSupport类的子类,一个AOP对象创建的辅助类,提供不同的AOP代理对象生成的通用方法,而代理对象的生成由其子类完成。
  • 实际创建AOP对象的类:AspectJProxyFactory、ProxyFactory、ProxyFactoryBean;工厂类;ProxyCreatorSupport的子类;
  1. AspectJProxyFactory:创建AspectJ的AOP对象,用于Spring集成AspectJ的作用,此时,就不需要使用AspectJ特定的编译器了。
  2. ProxyFactory:创建编程式的AOP对象;
  3. ProxyFactoryBean:创建声明式的AOP对象,通过配置创建AOP对象;

四、Spring AOP源码分析

以ProxyFactoryBean为例,分析Spring AOP的实现原理。

1.XML 配置




    
    
        com.test.Request
    

    
    
        
    

    
    
        
            logAdvice
        
    

    
    

2.ProxyFactoryBean生成AOP代理对象

ProxyFactoryBean配置目标对象和切面行为Advice,通过其配置的拦截器名称interceptorNames即通知器Advisor将切面应用到目标对象中。

ProxyFactoryBean的功能:

  1. 初始化通知器链
  2. 获取单例、原型的Aop代理对象

public class ProxyFactoryBean extends ProxyCreatorSupport
        implements FactoryBean, BeanClassLoaderAware, BeanFactoryAware {

    // 标记通知器的为全局通知器
    public static final String GLOBAL_SUFFIX = "*";

    // 通知器链是否已经初始化
    private boolean advisorChainInitialized = false;

    // 如果是单例,缓存单例对象
    private Object singletonInstance;

    // 实际上是:new DefaultAdvisorAdapterRegistry();Advisor适配器注册,将Advice适配成Advisor
    private AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance();


     // 创建AOPProxy代理对象的入口
    public Object getObject() throws BeansException {
        // 初始化通知器链
        initializeAdvisorChain();

        if (isSingleton()) { // 单例
            return getSingletonInstance();
        }
        else { // 原型
            if (this.targetName == null) {
                logger.warn("Using non-singleton proxies with singleton targets is often undesirable. " +
                        "Enable prototype proxies by setting the 'targetName' property.");
            }
            return newPrototypeInstance();
        }
    }

    // 初始化通知器链(同步方法)
    private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
        if (this.advisorChainInitialized) {
            // 如果通知器链已经初始化,直接返回
            return;
        }

        if (!ObjectUtils.isEmpty(this.interceptorNames)) { // 如果配置的拦截器名称存在
            // 如果没有bean容器,抛出异常
            if (this.beanFactory == null) {
                throw new IllegalStateException("No BeanFactory available anymore (probably due to serialization) " +
                        "- cannot resolve interceptor names " + Arrays.asList(this.interceptorNames));
            }

            // 全局通知器不能是通知器链中最后一个,除非显示的指定了目标
            if (this.interceptorNames[this.interceptorNames.length - 1].endsWith(GLOBAL_SUFFIX) &&
                    this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
                throw new AopConfigException("Target required after globals");
            }

            // 遍历通知器链名称
            for (String name : this.interceptorNames) {
                if (logger.isTraceEnabled()) {
                    logger.trace("Configuring advisor or advice '" + name + "'");
                }
                // 如果通知器是全局的
                if (name.endsWith(GLOBAL_SUFFIX)) {
                    if (!(this.beanFactory instanceof ListableBeanFactory)) {
                        throw new AopConfigException(
                                "Can only use global advisors or interceptors with a ListableBeanFactory");
                    }
                    // 向容器中添加全局通知器
                    addGlobalAdvisor((ListableBeanFactory) this.beanFactory,
                            name.substring(0, name.length() - GLOBAL_SUFFIX.length()));
                }
                // 否则,不是全局的
                else {
                    // 判断 通知器是否为单例
                    Object advice;
                    if (this.singleton || this.beanFactory.isSingleton(name)) { // 单例模式
                        // 添加实际的 Advisor/Advice 到链中
                        advice = this.beanFactory.getBean(name);
                    }
                    else { // 原型模式
                        // 如果是原型的 Advice or Advisor: 创建新的
                        // 避免通知器链初始化时没有必要的对象创建
                        advice = new PrototypePlaceholderAdvisor(name);
                    }
                    // 将Advice or Advisor添加的链中
                    addAdvisorOnChainCreation(advice, name);
                }
            }
        }

        // 设置通知器链初始化标识:已初始化
        this.advisorChainInitialized = true;
    }

    // 将Advice or Advisor添加的链中
    private void addAdvisorOnChainCreation(Object next, String name) {
        // 将提供的Advice、advisor转换为Advisor,以便匹配超类
        Advisor advisor = namedBeanToAdvisor(next);
        if (logger.isTraceEnabled()) {
            logger.trace("Adding advisor with name '" + name + "'");
        }
        // 加入到通知器链中
        addAdvisor(advisor);
    }

    // 将提供的Advice、Advisor转换为Advisor
    private Advisor namedBeanToAdvisor(Object next) {
        try {
            // 包装成Advisor通知器
            return this.advisorAdapterRegistry.wrap(next);
        }
        catch (UnknownAdviceTypeException ex) {
            // 如果提供的不是 Advisor or Advice, 抛出异常
            throw new AopConfigException("Unknown advisor type " + next.getClass() +
                    "; Can only include Advisor or Advice type beans in interceptorNames chain except for last entry," +
                    "which may also be target or TargetSource", ex);
        }
    }

    // 单例对象的 代理对象 构造
    private synchronized Object getSingletonInstance() {
        // singletonInstance 没有缓存单例代理对象,则创建,否则直接返回
        if (this.singletonInstance == null) {
            // 获取要代理的目标源
            this.targetSource = freshTargetSource();
            // 如果ProxyFactoryBean设置了自动探测接口属性(默认为True),且没有配置代理接口,且不是目标类的直接代理(ProxyConfig中默认为false)
            if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
                // 获取要代理对象的目标类
                Class targetClass = getTargetClass();
                if (targetClass == null) {
                    throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
                }
                // 获取目标类的接口
                setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
            }
            //初始化共享的单例对象
            // 设置是否使用ProxyConfig的默认配置:false,默认使用
            super.setFrozen(this.freezeProxy);
            // 创建AopProxy对象
            this.singletonInstance = getProxy(createAopProxy());
        }

        return this.singletonInstance;
    }

    // 原型对象的 代理对象 构造
    private synchronized Object newPrototypeInstance() {
        // In the case of a prototype, we need to give the proxy
        // an independent instance of the configuration.
        // In this case, no proxy will have an instance of this object's configuration,
        // but will have an independent copy.
        if (logger.isTraceEnabled()) {
            logger.trace("Creating copy of prototype ProxyFactoryBean config: " + this);
        }
        // 根据当前的工厂类,创建一个代理生成辅助类
        ProxyCreatorSupport copy = new ProxyCreatorSupport(getAopProxyFactory());
        // 辅助类需要一个新的通知器链和一个新的目标源
        TargetSource targetSource = freshTargetSource();
        // 代理生成辅助类,复制当前代理生成类的配置,新的目标源和通知器链
        copy.copyConfigurationFrom(this, targetSource, freshAdvisorChain());
        if (this.autodetectInterfaces && getProxiedInterfaces().length == 0 && !isProxyTargetClass()) {
            // 辅助类,设置接口
            copy.setInterfaces(
                    ClassUtils.getAllInterfacesForClass(targetSource.getTargetClass(), this.proxyClassLoader));
        }
        // 设置是否冻结默认配置
        copy.setFrozen(this.freezeProxy);

        if (logger.isTraceEnabled()) {
            logger.trace("Using ProxyCreatorSupport copy: " + copy);
        }
        // 通过辅助类创建代理对象,由此可见,每次原型的代理类,都是创建了一个新的copy
        return getProxy(copy.createAopProxy());
    }

}

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry {
    
    // 默认注册三类通知适配器
    public DefaultAdvisorAdapterRegistry() {
        registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        registerAdvisorAdapter(new ThrowsAdviceAdapter());
    }

    // 将Advice接口类适配为Advisor接口类,即将Advice包装成Advisor
    public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        // 如果指定的类型已经是通知器,直接返回
        if (adviceObject instanceof Advisor) {
            return (Advisor) adviceObject;
        }
        // 如果指定的类型不是Advice类型,直接抛出异常
        if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        }
        // 获取Advice
        Advice advice = (Advice) adviceObject;
        // 如果Advice是MethodInterceptor类型的
        if (advice instanceof MethodInterceptor) {
            // 直接返回默认的切点通知器
            return new DefaultPointcutAdvisor(advice);
        }
        // 否则使用注册的Advisor适配器对Advice核查(可自定义)
        for (AdvisorAdapter adapter : this.adapters) {
            // 核查是否支持
            if (adapter.supportsAdvice(advice)) {
                return new DefaultPointcutAdvisor(advice);
            }
        }
        // 不支持的通知类型,抛出异常
        throw new UnknownAdviceTypeException(advice);
    }

    protected Object getProxy(AopProxy aopProxy) {
        return aopProxy.getProxy(this.proxyClassLoader);
    }
    
}

 由源码可知,ProxyFactoryBean继承了ProxyCreatorSupport类,所以其本身就是创建AopProxy的工厂bean,其有个属性:AopProxyFactory,默认为DefaultAopProxyFactory;调用createAopProxy方法;

public class ProxyCreatorSupport extends AdvisedSupport {
    
    // AOP proxy 工厂类
    private AopProxyFactory aopProxyFactory;

    //当第一个AOPProxy代理对象被创建时,设置为true  
    private boolean active = false;

    // 默认使用DefaultAopProxyFactory生成代理对象
    public ProxyCreatorSupport() {
        this.aopProxyFactory = new DefaultAopProxyFactory();
    }

    // 通过子类的调用
    protected final synchronized AopProxy createAopProxy() {
        if (!this.active) {
            activate();
        }
        // 调用DefaultAopProxyFactory生成代理对象
        return getAopProxyFactory().createAopProxy(this);
    }

    // 激活代理配置,向容器注册代理回调监听器,第一次创建AOP代理时调用
    private void activate() {
        this.active = true;
        for (AdvisedSupportListener listener : this.listeners) {
            listener.activated(this);
        }
    }
}

接下来,看下默认工厂的创建方法:

public class DefaultAopProxyFactory implements AopProxyFactory, Serializable {

    @Override
    public AopProxy createAopProxy(AdvisedSupport config) throws AopConfigException {
        // ProxyConfig : optimize=false;
        // AOP显示优化 或 配置了目标类 或 使用了Spring支持的代理接口
        if (config.isOptimize() || config.isProxyTargetClass() || hasNoUserSuppliedProxyInterfaces(config)) {
            // 获取AOP配置的目标类
            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.");
            }
            // 如果配置的AOP目标类是接口,或者目标类已经是代理类,使用JDK动态代理
            if (targetClass.isInterface() || Proxy.isProxyClass(targetClass)) {
                return new JdkDynamicAopProxy(config);
            }
            // 否则使用CGLIB动态代理
            return new ObjenesisCglibAopProxy(config);
        }
        else {
            // 没有显示优化且没有配置目标类且没有使用代理接口,默认使用JDK动态代理
            return new JdkDynamicAopProxy(config);
        }
    }

    // 确定AdvisedSupport提供的配置,是否只配置了SpringProxy接口或者根本没有实现任何接口
    private boolean hasNoUserSuppliedProxyInterfaces(AdvisedSupport config) {
        // 获取AOP配置的所有接口
        Class[] ifcs = config.getProxiedInterfaces();
        return (ifcs.length == 0 || (ifcs.length == 1 && SpringProxy.class.isAssignableFrom(ifcs[0])));
    }
}

至此,SpringAOP的代理对象生成的流程走完了。

3.具体的两种代理对象生成源码

1、 JDK动态代理:

Spring AOP在invoke方法中,调用配置的通知器链;

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    
    // 代理对象使用的配置
    private final AdvisedSupport advised;

    // 通过 AdvisedSupport 配置构造一个JDK AOP代理对象
    public JdkDynamicAopProxy(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");
        }
        // 初始化AOP配置
        this.advised = config;
    }

    // 获取AOP代理对象的入口类
    public Object getProxy() {
        return getProxy(ClassUtils.getDefaultClassLoader());
    }

    // 创建AOP代理对象
    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }
        // 获取AOP配置的代理接口
        Class[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        // 查找代理目标的接口是否定义equals和hashcode方法
        findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);
        // 使用JDK动态代理创建AOP对象
        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

    // 通过内省去判断代理接口,是否有equals 和 hashCode方法
    private void findDefinedEqualsAndHashCodeMethods(Class[] proxiedInterfaces) {
        for (Class proxiedInterface : proxiedInterfaces) {
            Method[] methods = proxiedInterface.getDeclaredMethods();
            for (Method method : methods) {
                if (AopUtils.isEqualsMethod(method)) {
                    this.equalsDefined = true;
                }
                if (AopUtils.isHashCodeMethod(method)) {
                    this.hashCodeDefined = true;
                }
                if (this.equalsDefined && this.hashCodeDefined) {
                    return;
                }
            }
        }
    }

    // 实现 InvocationHandler,回调的方法
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        MethodInvocation invocation;
        Object oldProxy = null;
        boolean setProxyContext = false;
        // 通知的目标对象源
        TargetSource targetSource = this.advised.targetSource;
        Class targetClass = null;
        Object target = null;

        try {
            // 如果目标对象没有实现equals方法且当前调用equals方法
            if (!this.equalsDefined && AopUtils.isEqualsMethod(method)) {
                // 使用 提供的
                return equals(args[0]);
            }
            // 如果目标对象没有实现hashCode方法且当前调用hashCode方法
            else if (!this.hashCodeDefined && AopUtils.isHashCodeMethod(method)) {
                return hashCode();
            }
            // 如果目标方法只是DecoratingProxy,重定向到代理配置
            else if (method.getDeclaringClass() == DecoratingProxy.class) {
                return AopProxyUtils.ultimateTargetClass(this.advised);
            }
            // 如果AOP配置了通知,使用反射机制调用同名方法
            else if (!this.advised.opaque && method.getDeclaringClass().isInterface() &&
                    method.getDeclaringClass().isAssignableFrom(Advised.class)) {
                return AopUtils.invokeJoinpointUsingReflection(this.advised, method, args);
            }

            Object retVal;
            // 如果当前通知暴露了代理,将当前代理变为可用代理
            if (this.advised.exposeProxy) {
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }

            target = targetSource.getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }

            // 获取目标方法的拦截器链
            List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

            // 如果没有连接器
            if (chain.isEmpty()) {
                // 使用反射直接调用目标方法
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = AopUtils.invokeJoinpointUsingReflection(target, method, argsToUse);
            }
            else {
                // 创建方法回调对象
                invocation = new ReflectiveMethodInvocation(proxy, target, method, args, targetClass, chain);
                // 沿着拦截器链,执行通知
                retVal = invocation.proceed();
            }

            // 如果方法有返回值,则将代理对象作为方法返回
            Class returnType = method.getReturnType();
            if (retVal != null && retVal == target &&
                    returnType != Object.class && returnType.isInstance(proxy) &&
                    !RawTargetAccess.class.isAssignableFrom(method.getDeclaringClass())) {
                retVal = proxy;
            }
            // 如果返回不为void,返回为空,抛出异常
            else if (retVal == null && returnType != Void.TYPE && returnType.isPrimitive()) {
                throw new AopInvocationException(
                        "Null return value from advice does not match primitive return type for: " + method);
            }
            return retVal;
        }
        finally {
            if (target != null && !targetSource.isStatic()) {
                // 释放目标对象
                targetSource.releaseTarget(target);
            }
            if (setProxyContext) {
                // 存储当前代理对象
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }
}

调用AopUtils.invokeJoinpointUsingReflection()方法,回调目标类的方法

public static Object invokeJoinpointUsingReflection(Object target, Method method, Object[] args)
            throws Throwable {

    // 利用反射回调目标方法
    try {
        ReflectionUtils.makeAccessible(method);
        return method.invoke(target, args);
    }
}

2、CGLIB动态代理

class CglibAopProxy implements AopProxy, Serializable {
    
    // 获取代理对象
    public Object getProxy(ClassLoader classLoader) {
        try {
            // 获取要代理的目标类
            Class rootClass = this.advised.getTargetClass();
            // 将目标类做为基类(父类)
            Class proxySuperClass = rootClass;
            if (ClassUtils.isCglibProxyClass(rootClass)) { // 核查目标类是否已经是CGLIB动态代理对象
                // 获取其父类
                proxySuperClass = rootClass.getSuperclass();
                // 获取目标类的接口
                Class[] additionalInterfaces = rootClass.getInterfaces();
                // 将目标类的接口添加到AOP配置的接口中
                for (Class additionalInterface : additionalInterfaces) {
                    this.advised.addInterface(additionalInterface);
                }
            }

            // 验证基类
            validateClassIfNecessary(proxySuperClass, classLoader);

            // 配置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 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();
            }
            // 设置回调过滤器
            enhancer.setCallbackFilter(new ProxyCallbackFilter(
                    this.advised.getConfigurationOnlyCopy(), this.fixedInterceptorMap, this.fixedInterceptorOffset));
            // 设置回调方法的类型
            enhancer.setCallbackTypes(types);

            // 生成字节码流并创建代理对象
            return createProxyClassAndInstance(enhancer, callbacks);
        }
    }

    // 获取目标类的回调通知
    private Callback[] getCallbacks(Class rootClass) throws Exception {
        // 优化参数
        boolean exposeProxy = this.advised.isExposeProxy();
        boolean isFrozen = this.advised.isFrozen();
        boolean isStatic = this.advised.getTargetSource().isStatic();

        // 根据AOP配置创建一个动态通知拦截器,CGLIB创建的动态代理会自动调用  
        // DynamicAdvisedInterceptor类的intercept方法对目标对象进行拦截处理
        Callback aopInterceptor = new DynamicAdvisedInterceptor(this.advised);

        Callback targetInterceptor;
        if (exposeProxy) {
            targetInterceptor = isStatic ?
                    new StaticUnadvisedExposedInterceptor(this.advised.getTargetSource().getTarget()) :
                    new DynamicUnadvisedExposedInterceptor(this.advised.getTargetSource());
        }
        else {
            targetInterceptor = isStatic ?
                    new StaticUnadvisedInterceptor(this.advised.getTargetSource().getTarget()) :
                    new DynamicUnadvisedInterceptor(this.advised.getTargetSource());
        }

        Callback targetDispatcher = isStatic ?
                new StaticDispatcher(this.advised.getTargetSource().getTarget()) : new SerializableNoOp();
        // 创建目标分发器  
        Callback[] mainCallbacks = new Callback[] {
                aopInterceptor,  // for normal advice
                targetInterceptor,  // invoke target without considering advice, if optimized
                new SerializableNoOp(),  // no override for methods mapped to this
                targetDispatcher, this.advisedDispatcher,
                new EqualsInterceptor(this.advised),
                new HashCodeInterceptor(this.advised)
        };

        Callback[] callbacks;
        // 如果目标是静态的,并且通知链被冻结,则使用优化AOP调用,直接对方法使用
        if (isStatic && isFrozen) {
            Method[] methods = rootClass.getMethods();
            Callback[] fixedCallbacks = new Callback[methods.length];
            this.fixedInterceptorMap = new HashMap(methods.length);

            for (int x = 0; x < methods.length; x++) {
                List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(methods[x], rootClass);
                fixedCallbacks[x] = new FixedChainStaticTargetInterceptor(
                        chain, this.advised.getTargetSource().getTarget(), this.advised.getTargetClass());
                this.fixedInterceptorMap.put(methods[x].toString(), x);
            }
            //将固定回调和主要回调拷贝到回调数组中
            callbacks = new Callback[mainCallbacks.length + fixedCallbacks.length];
            System.arraycopy(mainCallbacks, 0, callbacks, 0, mainCallbacks.length);
            System.arraycopy(fixedCallbacks, 0, callbacks, mainCallbacks.length, fixedCallbacks.length);
            this.fixedInterceptorOffset = mainCallbacks.length;
        }
        else {
            //如果目标不是静态的,或者通知链不被冻结,则使用AOP主要的通知  
            callbacks = mainCallbacks;
        }
        return callbacks;
    }

}

看下: CglibAopProxy.DynamicAdvisedInterceptor,动态通知拦截器;回调目标类的方法;

private static class DynamicAdvisedInterceptor implements MethodInterceptor {
    public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
        Object oldProxy = null;
        boolean setProxyContext = false;
        Class targetClass = null;
        Object target = null;
        try {
            if (this.advised.exposeProxy) { // 如果通知暴露了代理
                // 当前代理对象也要被拦截
                oldProxy = AopContext.setCurrentProxy(proxy);
                setProxyContext = true;
            }
            // 获取目标对象
            target = getTarget();
            if (target != null) {
                targetClass = target.getClass();
            }
            // 获取通知器链
            List chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
            Object retVal;
            
            if (chain.isEmpty() && Modifier.isPublic(method.getModifiers())) {
                // 没有通知,直接调用目标方法
                Object[] argsToUse = AopProxyUtils.adaptArgumentsIfNecessary(method, args);
                retVal = methodProxy.invoke(target, argsToUse);
            }
            else {
                // 否则,创建方法执行器来回调方法
                retVal = new CglibMethodInvocation(proxy, target, method, args, targetClass, chain, methodProxy).proceed();
            }
            //获取目标对象对象方法的回调结果,如果有必要则封装为代理
            retVal = processReturnType(proxy, target, method, retVal);
            return retVal;
        }
        finally {
            if (target != null) {
                releaseTarget(target);
            }
            if (setProxyContext) {
                // 存储代理
                AopContext.setCurrentProxy(oldProxy);
            }
        }
    }
}

五、切点和切面分析

其实,有点分不清Spring 中Advice和Advisor的概念;

接下来分析一下:

5.1 切点和切面

Spring AOP中包含5中增强或者说通知

  • 方法执行前:org.apringframework.aop.MethodBeforeAdvice
  • 方法返回后: org.springframework.aop.AfterReturningAdvice
  • 异常抛出后:org.springframework.aop.ThrowsAdvice
  • 环绕(方法前后): org.aopaliance.intercept.MethodInterceptor
  • 引介(不常用) :org.springframework.aop.IntroductionInterceptor

有选择地织入到目标类某些特定的方法中,就需要使用切点进行目标连接点的定位,描述连接点;

Advice(org.aopalliance.aop.Advice接口):描述了增强的位置,方法前、后等;

PointCut(org.springframework.aop.Pointcut接口):描述了具体的哪些类、哪些方法上;Pointcut由ClassFilter和MethodMatcher构成;

public interface Pointcut {
    Pointcut TRUE = TruePointcut.INSTANCE;
    // 类过滤器,定位到特定的类上
    ClassFilter getClassFilter();
    // 方法匹配器,定位到特定的方法上
    MethodMatcher getMethodMatcher();
}

Spring 提供6中切点类型:

  1. 静态方法切点类型(org.springframework.aop.support.StaticMethodMatcherPointcut):抽象类;默认匹配所有的类;
    子类:NameMatchMethodPointcut(简单字符串匹配方法签名)和 AbstractRegexpMethodPointcut(正则表达式匹配方法签名);
  2. 动态方法切点类型(org.springframework.aop.support.DynamicMethodMatcherPointcut):抽象类;
  3. 注解切点类型(org.springframework.aop.support.annotation.AnnotationMatchingPointcut):JDK5以后,通过注解方式声明切点;
  4. 表达式切点类型(org.springframework.aop.support.ExpressionPointcut):通过表达式匹配,用于支持AspectJ的表达式;
  5. 流程切点(org.springframework.aop.support.ControlFlowPointcut):没用过;
  6. 复合切点(org.springframework.aop.support.ComposablePointcut):没用过;

切面由切点(pointcut)和增强(advice)组成,而advice中包含了增强的横切代码,pointcut包含了连接点的描述信息;

其实Spring中提供的增强MethodBeforeAdvice、AfterReturningAdvice等,也包含了连接点信息,就是一个切面,最终都会被AdvisorRegister转换成Advisor;

所以说,Spring 中的Advisor就是横切面的抽象,包含切点和增强;

Spring中的切面类型:

  1. Advisor:代表一般切面,它仅包含一个Advice,因为Advice包含了横切代码和连接点的信息,所以Advice本身就是一个简单的切面,只不过它代表的横切的连接点是所有目标类的所有方法。
  2. PointcutAdvisor:代表具有切点的切面,它包含Advice和Pointcut两个类,这样就可以通过类、方法名以及方法方位等信息灵活地定义切面的连接点,提供更具适用性的切面。
    其由6种实现类:
  • DefaultPointcutAdvisor:最常用的切面类型,它可以通过任意Pointcut和Advice定义一个切面,唯一不支持的是引介的切面类型,一般可以通过扩展该类实现自定义的切面;
  • NameMatchMethodPointcutAdvisor:通过该类可以定义,按方法名定义切点的切面;
  • RegexpMethodPointcutAdvisor:按正则表达式匹配方法名进行切点定义的切面;
  • StaticMethodMatcherPointcutAdvisor:静态方法匹配器切点定义的切面;
  • AspecJExpressionPointcutAdvisor:Aspecj切点表达式定义切点的切面;
  • AspecJPointcutAdvisor:使用AspecJ语法定义切点的切面;

多个Advisor通过org.springframework.core.Ordered接口,来确定增强的顺序;

5.2 Spring 自动代理机制

之前,是通过ProxyFactoryBean,生成targetClass的代理对象,从容器中获取使用,但是对于众多bean需要代理的情况下,就需要Spring的自动代理机制了。

Spring通过org.springframework.beans.factory.config.BeanPostProcessor自动地完成这项工作。其实现类有3种:

Spring AOP源码解读_第2张图片

  1. BeanNameAutoProxyCreator(基于Bean配置名规则的自动代理创建器):允许为一组特定配置名的Bean自动创建代理实例的代理创建器;
  2. DefaultAdvisorAutoProxyCreator(基于Advisor匹配机制的自动代理创建器):对容器中所有的Advisor进行扫描,自动将这些切面应用到匹配的Bean中(即为目标Bean创建代理实例);
  3. AnnotationAwareAspectjAutoProxyCreator(基于Bean中AspectJ注解标签的自动代理创建器):为包含AspectJ注解的Bean自动创建代理实例;

 
 

5.3 日常用Spring AOP

两种方式:

1.XML配置:aop标签;

2.注解方式:需要aspectjrt.jar,aspectjweaver.jar提供的AspectJ注解;

 

六、参考

  1. https://www.cnblogs.com/zhangxufeng/p/9160869.html 切点表达式用法

你可能感兴趣的:(个人学习)