动态代理梳理

AOP 术语:

连接点(Joinpoint):指程序执行的某个特定位置,由两个信息确定:一是用方法表示程序的执行点;二是用相对位置表示的方位。

切点(Pointcut):每个程序有多个连接点,而切点则是定位特定的连接点。类似于数据库条件查询,链接点为数据库中的记录,切点相当于查询条件。(切点只能具体到某个方法,要想找到具体的连接点还得通过增强(Advice)中的方位结合)。

增强(Advice):增强中除了描述一段程序代码之外,还拥有一个和连接点相关的信息,即执行点的方位,(通过切点和执行点的方位就能找到特定的连接)。

目标对象(Target): 增强逻辑的织入目标类。

引介(Introduction):一种特殊的增强,它不是为目标方法周围织入增强,它是为目标类添加一些属性和方法。所以引介增强的连接点是类级别的,而非方法级别。(注意:因为是对类进行操作,所以在生成代理对象的时候我们必须指定AOP底层用CGLib方式生成代理对象,并且还得指定要实现的接口。),这样就算业务类没有实现某个接口,也可以通过AOP的引介功能,动态的为该类添加接口的实现,让业务类成为这个接口的实现。

织入(Weaving):织入是将增强添加到目标类的具体连接点上的过程。AOP三种织入方式:

        a:编译期织入,要求使用特殊的编译器

        b:类装载期织入,使用特殊的类加载器

        c:动态代理织入,在运行期间为目标类添加增强生成子类的方式,Spring采用动态代理织入,AspectJ采用a,b两种方式。

7:代理(Proxy):一个类被AOP织入增强逻辑之后产生的一个类,它是融合了原类和增强逻辑的代理类,根据代理方式不同,代理类可能是和原类具有相同的接口(JDK代理),也可能是原类的子类(CGLib代理)

切面(Aspect):切面由切点和增强(引介)组成。

JDK动态代理

*JDK动态代理 为接口创建代理实例,(类似于为接口创建实现类)

1:主要涉及java.lang.reflect包中的两个类ProxyInvocationHandler。其中InvocationHandler是个接口,可以自定义类实现该接口,从而定义增强逻辑,然后通过反射机制调用目标类的代码,动态的将横切(增强)逻辑和业务逻辑编织在一起。

代码示例:

1:目标类实现了JDKProxyInterface 接口

package springAop;

/**
 * 目标类
 */
public class JDKProxyImp implements JDKProxyInterface {
    @Override
    public void say() {
        System.out.println("Hello JdkDynamicAopProxy");
    }
}

2:增强逻辑: InvocationHandler 实现类

package springAop;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;

public class MyInvocationHandler implements InvocationHandler {
    private Object object;
    //invoke()中要通过反射执行目标类的方法,所以还得需要传入目标实例,此处通过构造函数传入目标实例
    public MyInvocationHandler(Object o){
        this.object = o;
    }
    /**
     *
     * @param proxy  最终生成的代理实例,一般不使用
     * @param method 被代理目标实例的某个具体方法,通过它可以发起目标实例方法的反射调用,
     * @param args   被代理实例某个方法的入参,在反射调用时使用
     * @return
     * @throws Throwable
     */
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        //这里可以写目标方法执行前的横切逻辑,即spring Aop 中的前置增强(MethodBeforeAdvice)
        System.out.println("前置增强,类似MethodBeforeAdvice");
        Object result = method.invoke(object,args);
        //后置增强
        System.out.println("后置增强,类似AfterReturningAdvice");
        return result;
    }
}

 3:调用逻辑:通过Proxy.newProxyInstance()方法为目标类创建代理对象

    @Test
    public void JDK动态代理(){
        JDKProxyInterface jDKProxyInterface = new JDKProxyImp();
        MyInvocationHandler myInvocationHandler = new MyInvocationHandler(jDKProxyInterface);
        JDKProxyInterface proxy = (JDKProxyInterface) Proxy.newProxyInstance(
                jDKProxyInterface.getClass().getClassLoader(),
                jDKProxyInterface.getClass().getInterfaces(),
                myInvocationHandler);
        proxy.say();
    }
}

4:运行结果:

CGLib动态代理

* 为没有实现接口的类创建代理对象,实在底层采用的是字节码技术,可以为一个类创建子类,子类中采用方法拦截的技术拦截所有父类方法的调用并顺势织入横切逻辑

代码示例:

1:通过Enhancer 类为目标类生成代理子类,

2:实现org.springframework.cglib.proxy包下的MethodInterceptor接口并实现其interceptor()方法

package springAop;
import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;
import java.util.Arrays;

public class CglibProxy implements MethodInterceptor {
    /**
     * 利用Enhancer为目标对象生成代理对象
     * @param clazz
     * @return
     */
    public Object getProxy(Class clazz){
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(clazz); //设置需要创建子类的类
        enhancer.setCallback(this);
        return enhancer.create(); //利用字节码技术动态创建子类实例
    }

    /**
     *
     * @param o  目标类实例
     * @param method   目标类方法的反射对象
     * @param objects  目标类方法的动态入参
     * @param proxy 代理类实例
     * @return
     * @throws Throwable
     */
    @Override
    //会拦截父类的所有方法,这里的父类就是clazz对应的对象
    public Object intercept(Object o, Method method, Object[] objects, MethodProxy proxy) throws Throwable {
        System.out.println("目标类实例:"+o.getClass().getName()+",目标类方法反射对象"+method.getName()
                +",目标方法参数列表:"+ Arrays.toString(objects)+",代理类实例:"+proxy);
        System.out.println("增强逻辑");
        Object result = proxy.invokeSuper(o,objects);  //通过代理方法调用父类的方法
        //返回目标方法执行结果
        System.out.println("目标方法输出结果:"+result);
        return result;
    }
}

调用逻辑:

    @Test
    public void CGlib动态代理(){
        CglibTest target = new CglibTest();
        CglibProxy cglibProxy = new CglibProxy();
        CglibTest proxy = (CglibTest) cglibProxy.getProxy(target.getClass());
        proxy.add(1,3);
    }

结果:

总结:

问题1:JDK动态代理和CGLib动态代理,会为目标类的所有方法都添加增强逻辑,没有做到为指定类的指定方法做增强。

问题2:代码耦合,通过硬编码的方式制定了增强逻辑的织入点,即在目标方法的开始前或结束前。

问题3:在创建代理实例的过程中,在为不同类创建代理时,需要分别编写相应的创建代码,无法做到通用。

 Spring AOP

1:Spring Aop中为我们引入了Pointcut(切点)类,指定在那些类的那些方法上织入横切逻辑。

2:引入Advice(增强):它描述了增强逻辑以及方法的具体织入点(方法前,方法后,方法的两端等,方法抛出异常后)。

3:另外Spring Aop 还引入了Advisor(切面),将Pointcut和Advice组装起来,有了Advisor的信息,spring底层就可以利用JDK或者CGLib动态代理技术采用同一的方式为目标Bean创建织入切面的代理对象。Spring Aop通过这三点正好解决了前面的三个问题。

Spring AOP增强类型 :5类

1:前置增强 org.aopalliance.aop.BeforeAdvice接口,Spring只支持对方法的增强,所以一般使用MethodBeforeAdvice接口。目标方法调用之前实施增强

2:后置增强:org.springframework.aop.AfterReturningAdvice接口,代表在目标方法执行后事实增强

3:环绕增强 org.aopalliance.intercept.MethodInterceptor接口,代表在目标方法执行前后实施增强

4:异常抛出增强: org.springframework.aop.ThrowsAdvice  表示在目标方法抛出异常后实施增强(例如:事务回滚机制),

5:引介增强:org.springframework.aop.IntroductionInterceptor 表示在目标类中添加一些新的方法和属性。(由于引介增强接口IntroductionInterceptor没有定义任何方法所以一般通过扩展它 的实现类DelegatingIntroductionInterceptor类定义自己的引介增强)

注意ThrowsAdvice接口是个标签接口,没有指定方法,在运行期间Spring使用反射机制自行判断,必须采用以下签名形式定义异常抛出的增强方法:

void afterThrowing([Method method,Object[] args,Object target],Throwable)

1:方法名必须为afterThrowing

2:  方法入参:要么为4个,要么1个,前三个为可选参数,最后一个参数必须有,类型为Throwable或其子类。

原因可参考,

org.springframework.aop.framework.adapter.ThrowsAdviceInterceptor类,因为ThrowsAdvice类型的切面会被ThrowsAdviceAdapter封装成ThrowsAdviceInterceptor:

ThrowsAdviceAdapter源代码:
//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.aop.framework.adapter;

import java.io.Serializable;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.ThrowsAdvice;

class ThrowsAdviceAdapter implements AdvisorAdapter, Serializable {
    ThrowsAdviceAdapter() {
    }

    public boolean supportsAdvice(Advice advice) {
        return advice instanceof ThrowsAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor) {
        return new ThrowsAdviceInterceptor(advisor.getAdvice());
    }
}

ThrowsAdviceInterceptor部分源代码:

其中会判断方法名是否是:afterThrowing,方法参数是1个或者4个,最后一个参数类型是否是Throwable或其子类。

public class ThrowsAdviceInterceptor implements MethodInterceptor, AfterAdvice {
    private static final String AFTER_THROWING = "afterThrowing";
    private static final Log logger = LogFactory.getLog(ThrowsAdviceInterceptor.class);
    private final Object throwsAdvice;
    private final Map<Class<?>, Method> exceptionHandlerMap = new HashMap();

    public ThrowsAdviceInterceptor(Object throwsAdvice) {
        Assert.notNull(throwsAdvice, "Advice must not be null");
        this.throwsAdvice = throwsAdvice;
        Method[] methods = throwsAdvice.getClass().getMethods();
        Method[] var3 = methods;
        int var4 = methods.length;

        for(int var5 = 0; var5 < var4; ++var5) {
            Method method = var3[var5];
            if (method.getName().equals("afterThrowing") && (method.getParameterTypes().length == 1 || method.getParameterTypes().length == 4) && Throwable.class.isAssignableFrom(method.getParameterTypes()[method.getParameterTypes().length - 1])) {
                this.exceptionHandlerMap.put(method.getParameterTypes()[method.getParameterTypes().length - 1], method);
                if (logger.isDebugEnabled()) {
                    logger.debug("Found exception handler method: " + method);
                }
            }
        }

        if (this.exceptionHandlerMap.isEmpty()) {
            throw new IllegalArgumentException("At least one handler method must be found in class [" + throwsAdvice.getClass() + "]");
        }
    }

异常通知示例:ThrowsAdvice

package springAop;

import org.springframework.aop.ThrowsAdvice;

import java.lang.reflect.Method;

/**
 * 异常通知中可以定义多个方法,当目标方法抛出异常之后,调用那个增强方法原理:
 * 在类的继承树上,两个类的距离越近,就说明两个类的相似度越高,目标方法抛出异常之后,
 * 会优先选择拥有异常入参和抛出异常相似度最高的afterThrowing方法
 */
public class MyThrowsAdvice implements ThrowsAdvice {
    public void afterThrowing(Exception e){
        System.out.println("异常通知 一个参数");
    };

    public void afterThrowing(Method method,Object[] args, Object target, ArithmeticException e){
        System.out.println("异常通知 4个参数");
    };
}

目标类:

package springAop;

public class CglibTest {

    public void testThrowsAdvice(){
        System.out.println("异常通知中有两个方法,会根据异常类型相近的选择异常增强方法");
        System.out.println(10/0);
    }

    public void testThrowsAdvice2(){
        throw  new RuntimeException("异常通知,选择方法按照异常就近原则");
    }
}

调用

    @Test
    public  void test异常通知(){
        ProxyFactory pf = new ProxyFactory();
        pf.addAdvice(new MyThrowsAdvice());
        pf.setTarget(new CglibTest());
        CglibTest proxy = (CglibTest)pf.getProxy();
       // proxy.testThrowsAdvice();
        proxy.testThrowsAdvice2();
    }

testThrowsAdvice2()运行结果:抛出的是RuntimeException异常,所以由

public void afterThrowing(Exception e)方法处理。

 testThrowsAdvice()运行结果:因为抛出的是ArithmeticException异常所以调用参数是ArithmeticException的方法

引介增强示例:

1:定义需要为目标类实现的接口

package springAop.introduction;

/**
 * 通过引介增强为目标类实现的接口
 */
public interface TargetInterface {
    public void sayHello(String name);
}

2:目标业务类,没有实现上面接口:

package springAop.introduction;

public class TargetDemo {
    public void say(){
        System.out.println("目标类中原始方法");
    }
}

3:扩展DelegatingIntroductionInterceptor并实现TargetInterface接口的sayHello(String name)

package springAop.introduction;

import org.springframework.aop.support.DelegatingIntroductionInterceptor;

/**
 * 通过扩展引介增强接口IntroductionInterceptor 的实现类DelegatingIntroductionInterceptor类定义自己的引介增强
 * 并且实现需要为目标业务类实现的接口TargetInterface
 */
public class MyIntroductionInterceptor extends DelegatingIntroductionInterceptor  implements TargetInterface{

    @Override
    public void sayHello(String name) {
        System.out.println("hello "+name);
    }
}

4: 配置引介增强:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 配置ProxyFactoryBean类负责为目标bean生成代理类-->
    <bean id="proxyFactoryBean1" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 设置引介增强所实现的接口-->
        <property name="interfaces" value="springAop.introduction.TargetInterface"></property>
        <!-- 配置目标业务类-->
        <property name="target" ref="target"></property>
        <!-- 配置需要织入目标业务类的增强bean名称,这里即为扩展了DelegatingIntroductionInterceptor的类-->
        <property name="interceptorNames" value="introduction"></property>
        <!-- 由于引介增强只能通过为目标类创建子类的方式生成引介增强的代理,所以必须将proxyTargetClass属性设置为true -->
        <property name="proxyTargetClass" value="true"></property>
    </bean>
    <!--目标业务Bean-->
    <bean id="target" class="springAop.introduction.TargetDemo">
    </bean>
    <!--引介增强Bean-->
    <bean id = "introduction" class="springAop.introduction.MyIntroductionInterceptor"></bean>
</beans>

5:测试代码及结果:

    @Test
    public void Test_引介增强(){
        TargetDemo targetDemo = (TargetDemo)applicationContext.getBean("proxyFactoryBean1");
        //为目标类实现了TargetInterface接口,所以能强转成TargetInterface
        TargetInterface targetInterface = (TargetInterface) targetDemo;
        targetDemo.say();
        //调用sayHello方法
        targetInterface.sayHello("你好");
    }

 ProxyFactory类:

常用属性和方法:

public void setInterfaces(Class... interfaces) :指定目标接口进行代理,则ProxyFactory使用JdkDynamicAopProxy 
public void addAdvice(Advice advice):指定使用增强逻辑
public void setProxyTargetClass(boolean proxyTargetClass) :指定是否对类进行代理,设置为true时,使用CGLib代理
setOptimize(true): 启动优化代理方式,这样针对接口的代理也会使用CglibAopProxy
ProxyFactory pf = new ProxyFactory();
//添加切面
pf.addAdvice(new MyThrowsAdvice());
//设置目标业务类
pf.setTarget(new CglibTest());
CglibTest proxy = (CglibTest)pf.getProxy();
proxy.testThrowsAdvice();
proxy.testThrowsAdvice2();
org.springframework.aop.framework.ProxyFactory类,getProxy()方法实际上是使用的JDk或CGLib动态技术。

它的getProxy()方法实际上是通过DefaultAopProxyFactory类创建AopProxy实例。

AopProxy继承关系:

 然后再调用每个实例的getProxy()方法获取代理对象。

例如CglibAopProxy类的getProxy()方法,其原理就是前面讲到的CGLib动态代理技术

    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating CGLIB proxy: target source is " + 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 (ClassUtils.isCglibProxyClass(rootClass)) {
                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);
            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 CglibAopProxy.ClassLoaderAwareUndeclaredThrowableStrategy(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 (CodeGenerationException var9) {
            throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: Common causes of this problem include using a final class or a non-visible class", var9);
        } catch (IllegalArgumentException var10) {
            throw new AopConfigException("Could not generate CGLIB subclass of class [" + this.advised.getTargetClass() + "]: Common causes of this problem include using a final class or a non-visible class", var10);
        } catch (Throwable var11) {
            throw new AopConfigException("Unexpected AOP exception", var11);
        }
    }
JdkDynamicAopProxy 原理,实际上也是通过java.lang.reflect.Proxy类和java.lang.reflect.InvocationHandler接口底层(即和JDK代理原理相同)
//JdkDynamicAopProxy 实现了InvocationHandler,AopProxy
final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable {
    .......其他方法省略....
    public Object getProxy(ClassLoader classLoader) {
        if (logger.isDebugEnabled()) {
            logger.debug("Creating JDK dynamic proxy: target source is " + this.advised.getTargetSource());
        }

        Class<?>[] proxiedInterfaces = AopProxyUtils.completeProxiedInterfaces(this.advised, true);
        this.findDefinedEqualsAndHashCodeMethods(proxiedInterfaces);

        //其底层也是使用的Prxoy类newProxyInstance()方法

        return Proxy.newProxyInstance(classLoader, proxiedInterfaces, this);
    }

ProxyFactoryBean类:

继承关系图

 由于ProxyFactoryBean实现了FactoryBean接口:

所以通过

TestAop aop = (TestAop) applicationContext.getBean("proxyFactoryBean"); 获取的对象实际上是目标对象的代理对象。

部分代码如下:

//如果没有初始化切面链,则调用 initializeAdvisorChain方法初始化,然后根据目标类获取代理对象,如果是单例则调用getSingletonInstance,prototype模式则调用newPrototypeInstance
public Object getObject() throws BeansException {
        this.initializeAdvisorChain();
        if (this.isSingleton()) {
            return this.getSingletonInstance();
        } else {
            if (this.targetName == null) {
                this.logger.warn("Using non-singleton proxies with singleton targets is often undesirable. Enable prototype proxies by setting the 'targetName' property.");
            }

            return this.newPrototypeInstance();
        }
    }

//以单例模式为例,通过AopProxyFactory的实现类DefaultAopProxyFactory为目标类targetClass生成代理对象
    private synchronized Object getSingletonInstance() {
        if (this.singletonInstance == null) {
            this.targetSource = this.freshTargetSource();
            if (this.autodetectInterfaces && this.getProxiedInterfaces().length == 0 && !this.isProxyTargetClass()) {
                Class<?> targetClass = this.getTargetClass();
                if (targetClass == null) {
                    throw new FactoryBeanNotInitializedException("Cannot determine target class for proxy");
                }

                this.setInterfaces(ClassUtils.getAllInterfacesForClass(targetClass, this.proxyClassLoader));
            }

            super.setFrozen(this.freezeProxy);
            this.singletonInstance = this.getProxy(this.createAopProxy());
        }

        return this.singletonInstance;
    }



//DefaultAopProxyFactory类的createAopProxy方法
//判断ProxyFactoryBean是否Optimize和ProxyTargetClass没有指定为true,以及实现了接口则使用JdkDynamicAopProxy
//如果目标类不是接口,且不是Proxy类则使用ObjenesisCglibAopProxy(CglibAopProxy的子类)

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

 常用配置属性:

target:代理的目标对象

proxyInterfaces: 代理所要实现的接口,

interceptorNames:需要织入目标对象的Bean列表,采用Bean的名称指定,这些Bean必须是org.aopalliance.intercept.MethodInterceptor和org.springframework.aop.Advisor类型,也可以为通配符*,或者Advice类型,配置中的顺序对应调用的顺序。

如果interceptorNames含有统配符*,

ProxyFactoryBean会调用initializeAdvisorChain()方法,初始化增强链。源码如下:
//解析interceptorNames属性的值,初始化增强链  
private synchronized void initializeAdvisorChain() throws AopConfigException, BeansException {
        if (!this.advisorChainInitialized) {
            if (!ObjectUtils.isEmpty(this.interceptorNames)) {
                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("*") && this.targetName == null && this.targetSource == EMPTY_TARGET_SOURCE) {
                    throw new AopConfigException("Target required after globals");
                }

                String[] var1 = this.interceptorNames;
                int var2 = var1.length;

                for(int var3 = 0; var3 < var2; ++var3) {
                    String name = var1[var3];
                    if (this.logger.isTraceEnabled()) {
                        this.logger.trace("Configuring advisor or advice '" + name + "'");
                    }

                    if (name.endsWith("*")) {
                        if (!(this.beanFactory instanceof ListableBeanFactory)) {
                            throw new AopConfigException("Can only use global advisors or interceptors with a ListableBeanFactory");
                        }

                        this.addGlobalAdvisor((ListableBeanFactory)this.beanFactory, name.substring(0, name.length() - "*".length()));
                    } else {
                        Object advice;
                        if (!this.singleton && !this.beanFactory.isSingleton(name)) {
                            advice = new ProxyFactoryBean.PrototypePlaceholderAdvisor(name);
                        } else {
                            advice = this.beanFactory.getBean(name);
                        }

                        this.addAdvisorOnChainCreation(advice, name);
                    }
                }
            }

            this.advisorChainInitialized = true;
        }
    }

处理逻辑:

1:判断是否包含统配符*结尾,是则通过addGlobalAdvisor()方法根据Bean的 name从容器beanFactory中获取所有Advisor和Interceptor类型的Bean,然后通过addAdvisorOnChainCreation(bean, name)添加到增强链

addGlobalAdvisor代码如下:

//如果名称中以通配符*结尾,会将*前面的字符串作为Bean name前缀来匹配 
private void addGlobalAdvisor(ListableBeanFactory beanFactory, String prefix) {
        String[] globalAdvisorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Advisor.class);
        String[] globalInterceptorNames = BeanFactoryUtils.beanNamesForTypeIncludingAncestors(beanFactory, Interceptor.class);
        List<Object> beans = new ArrayList(globalAdvisorNames.length + globalInterceptorNames.length);
        Map<Object, String> names = new HashMap(beans.size());
        String[] var7 = globalAdvisorNames;
        int var8 = globalAdvisorNames.length;

        int var9;
        String name;
        Object bean;
        for(var9 = 0; var9 < var8; ++var9) {
            name = var7[var9];
            bean = beanFactory.getBean(name);
            beans.add(bean);
            names.put(bean, name);
        }

        var7 = globalInterceptorNames;
        var8 = globalInterceptorNames.length;

        for(var9 = 0; var9 < var8; ++var9) {
            name = var7[var9];
            bean = beanFactory.getBean(name);
            beans.add(bean);
            names.put(bean, name);
        }

        AnnotationAwareOrderComparator.sort(beans);
        Iterator var12 = beans.iterator();

        while(var12.hasNext()) {
            Object bean = var12.next();
            String name = (String)names.get(bean);
            if (name.startsWith(prefix)) {
                this.addAdvisorOnChainCreation(bean, name);
            }
        }

    }
this.addGlobalAdvisor((ListableBeanFactory)this.beanFactory, 
name.substring(0, name.length() - "*".length()));

2:如果没有以*结尾,则判断当前name 是单例模式还是Prototyp类型,单例模式则从容器中获取Bean,最后也通过addAdvisorOnChainCreation()

    private void addAdvisorOnChainCreation(Object next, String name) {
        Advisor advisor = this.namedBeanToAdvisor(next);
        if (this.logger.isTraceEnabled()) {
            this.logger.trace("Adding advisor with name '" + name + "'");
        }

        this.addAdvisor(advisor);
    }

3:利用namedBeanToAdvisor()方法将对应的interceptorNames属性中Bean name对应的Bean封装成对应的advisor,然后将advisor设置到ProxyFactoryBean的List<Advisor> advisors中,等价于通过addAdvisor(advisor)

    private Advisor namedBeanToAdvisor(Object next) {
        try {
            return this.advisorAdapterRegistry.wrap(next);
        } catch (UnknownAdviceTypeException var3) {
            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", var3);
        }
    }

4:利用单例模式:AdvisorAdapterRegistry advisorAdapterRegistry = GlobalAdvisorAdapterRegistry.getInstance()生成DefaultAdvisorAdapterRegistry类的实例

package org.springframework.aop.framework.adapter;

//通过单例模式生成DefaultAdvisorAdapterRegistry
public abstract class GlobalAdvisorAdapterRegistry {
    private static AdvisorAdapterRegistry instance = new DefaultAdvisorAdapterRegistry();

    public GlobalAdvisorAdapterRegistry() {
    }

    public static AdvisorAdapterRegistry getInstance() {
        return instance;
    }

    static void reset() {
        instance = new DefaultAdvisorAdapterRegistry();
    }
}

DefaultAdvisorAdapterRegistry类:

//
// Source code recreated from a .class file by IntelliJ IDEA
// (powered by Fernflower decompiler)
//

package org.springframework.aop.framework.adapter;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.support.DefaultPointcutAdvisor;

public class DefaultAdvisorAdapterRegistry implements AdvisorAdapterRegistry, Serializable {
    private final List<AdvisorAdapter> adapters = new ArrayList(3);

//创建对象时,初始化3个AdviceAdapter,对应BeforeAdvice,AfterReturingAdvice,ThrowsAdvice
    public DefaultAdvisorAdapterRegistry() {
        this.registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
        this.registerAdvisorAdapter(new AfterReturningAdviceAdapter());
        this.registerAdvisorAdapter(new ThrowsAdviceAdapter());
    }

//将Advice,MethodInterceptor包装成DefaultPointcutAdvisor,如果是advisor直接返回
//如果是advice,则判断是否有AdviceAdapter支持该类型的Advice,不支持则提示类型有误
    public Advisor wrap(Object adviceObject) throws UnknownAdviceTypeException {
        if (adviceObject instanceof Advisor) {
            return (Advisor)adviceObject;
        } else if (!(adviceObject instanceof Advice)) {
            throw new UnknownAdviceTypeException(adviceObject);
        } else {
            Advice advice = (Advice)adviceObject;
            if (advice instanceof MethodInterceptor) {
                return new DefaultPointcutAdvisor(advice);
            } else {
                Iterator var3 = this.adapters.iterator();

                AdvisorAdapter adapter;
                do {
                    if (!var3.hasNext()) {
                        throw new UnknownAdviceTypeException(advice);
                    }

                    adapter = (AdvisorAdapter)var3.next();
                } while(!adapter.supportsAdvice(advice));

                return new DefaultPointcutAdvisor(advice);
            }
        }
    }


//通过AdviceAdapter的getInterceptor()方法,将Advice转换成对应的MethodInterceptor类型
    public MethodInterceptor[] getInterceptors(Advisor advisor) throws UnknownAdviceTypeException {
        List<MethodInterceptor> interceptors = new ArrayList(3);
        Advice advice = advisor.getAdvice();
        if (advice instanceof MethodInterceptor) {
            interceptors.add((MethodInterceptor)advice);
        }

        Iterator var4 = this.adapters.iterator();

        while(var4.hasNext()) {
            AdvisorAdapter adapter = (AdvisorAdapter)var4.next();
            if (adapter.supportsAdvice(advice)) {
                interceptors.add(adapter.getInterceptor(advisor));
            }
        }

        if (interceptors.isEmpty()) {
            throw new UnknownAdviceTypeException(advisor.getAdvice());
        } else {
            return (MethodInterceptor[])interceptors.toArray(new MethodInterceptor[interceptors.size()]);
        }
    }

    public void registerAdvisorAdapter(AdvisorAdapter adapter) {
        this.adapters.add(adapter);
    }
}

DefaultAdvisorAdapterRegistry 创建时创建了三个切面适配器:

this.registerAdvisorAdapter(new MethodBeforeAdviceAdapter());
this.registerAdvisorAdapter(new AfterReturningAdviceAdapter());
this.registerAdvisorAdapter(new ThrowsAdviceAdapter());

DefaultAdvisorAdapterRegistry 方法介绍:

wrap():将Advice,MethodInterceptor包装成DefaultPointcutAdvisor,如果是advisor直接返回
如果是advice,则判断是否有AdviceAdapter支持该类型的Advice(调用supportsAdvice()),不支持则提示类型有误。

 public MethodInterceptor[] getInterceptors(Advisor advisor) : 将Advisor 中的Advice类型判断如果是MethodInterceptor(环绕通知)类型,则直接放入interceptors中,如果是Advice类型,则通过对应的AdvisorAdapter适配器中的getInterceptor()方法,转换成对应的MethodInterceptor

List<MethodInterceptor> interceptors = new ArrayList(3);

三个切面适配器都是AdvisorAdapter 接口的实现类,该接口包含两个方法,如下:

public interface AdvisorAdapter {
//当前适配器支持那种类型的切面
    boolean supportsAdvice(Advice var1);

//将切面转换成MethodInterceptor 
    MethodInterceptor getInterceptor(Advisor var1);
}

以MethodBeforeAdviceAdapter 为例

//支持MethodBeforeAdvice
class MethodBeforeAdviceAdapter implements AdvisorAdapter, Serializable {
    MethodBeforeAdviceAdapter() {
    }

    public boolean supportsAdvice(Advice advice) {
        return advice instanceof MethodBeforeAdvice;
    }

    public MethodInterceptor getInterceptor(Advisor advisor) {
        MethodBeforeAdvice advice = (MethodBeforeAdvice)advisor.getAdvice();
        return new MethodBeforeAdviceInterceptor(advice);
    }
}

Advice-AdvisorAdapter-MethodInterceptor对应关系
MethodBeforeAdvice
MethodBeforeAdviceAdapter
MethodBeforeAdviceInterceptor
AfterReturningAdvice
AfterReturningAdviceAdapter
AfterReturningAdviceInterceptor
ThrowsAdvice
ThrowsAdviceAdapter
ThrowsAdviceInt

下面是我自己定义的一个切面适配器 

综上所述: 

interceptorNames:织入目标对象的Bean列表,采用Bean的名称指定,这些Beanlei类型必须是org.aopalliance.intercept.MethodInterceptor和org.springframework.aop.Advisor类型,也可以为通配符*,或者Advice类型,配置中的顺序对应调用的顺序。

其中Advisor类型和Advice类型必须是以下三种实现类。

MethodBeforeAdvice
AfterReturningAdvice
ThrowsAdvice

另外interceptorNames中可以用通配符*,这样会将容器中存在的所有Advisor和Interceptorler类型的数据放入切面链中,例如myAfter*,会将Bean name 以myAfter为前缀的Advisor和Interceptorler类型放入切面链。

代码示例:

还是以引介增强当时的例子测试:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        https://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 配置ProxyFactoryBean类负责为目标bean生成代理类-->
    <bean id="proxyFactoryBean1" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 设置引介增强所实现的接口-->
        <property name="interfaces" value="springAop.introduction.TargetInterface"></property>
        <!-- 配置目标业务类-->
        <property name="target" ref="target"></property>
        <!-- 配置需要织入目标业务类的增强bean名称,这里即为扩展了DelegatingIntroductionInterceptor的类-->
<!--interceptorNames属性可以为org.aopalliance.intercept.MethodInterceptor和org.springframework.aop.Advisor类型的bean 名称或者*或者以*结尾,以及Advice类型的Bean-->
        <property name="interceptorNames" value="*,myMethodBeforeAdvice"></property>
        <!-- 由于引介增强只能通过为目标类创建子类的方式生成引介增强的代理,所以必须将proxyTargetClass属性设置为true -->
        <property name="proxyTargetClass" value="true"></property>
    </bean>
    <!--目标业务Bean-->
    <bean id="target" class="springAop.introduction.TargetDemo">
    </bean>
    <!--引介增强Bean-->
    <bean id = "introduction" class="springAop.introduction.MyIntroductionInterceptor"></bean>
<!--前置通知-->
    <bean id = "myMethodBeforeAdvice" class="springAop.MyMethodBeforeAdvice"></bean>
</beans>

测试截图:

含有统配*会将容器中匹配上的所有Advisor和Interceptorler类型的数据放入切面链中

 Advice类型的增强放入切面链

 最终将两个增强封装成了两个Advisor

 运行结果:

 interceptorNames属性中的introduction换成通配符*,也会将MyIntroductionInterceptor引介增强织入目标类,这是因为MyIntroductionInterceptor是org.aopalliance.intercept.Interceptor类型的,所以会放入切面链。

扩展:

总而言之ProxyFactoryBean目前仅支持org.aopalliance.intercept.MethodInterceptor和org.springframework.aop.Advisor类型和这三种Advice:MethodBeforeAdvice,AfterReturningAdvice,ThrowsAdvice。

如果想他支持其他类型的Advice,结合前面学的我们必须实现org.springframework.aop.framework.adapter.AdvisorAdapter和org.aopalliance.intercept.MethodInterceptor两个接口

AdvisorAdapter原理讲解:

两个方法:

1:public boolean supportsAdvice(Advice advice) //指定该适配器支持那种类型切面
2:public MethodInterceptor getInterceptor(Advisor advisor) //将切面转换成MethodInterceptor以便在
CglibAopProxy的DynamicAdvisedInterceptor动态获取切面拦截器List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);
JdkDynamicAopProxy代理的invoke方法中获取通过List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

实际上是调用AdvisorChainFactory接口的实现类DefaultAdvisorChainFactory

List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised var1, Method var2, Class<?> var3);  //根据目标方法和目标类以及切面获取Interceptor

DefaultAdvisorChainFactory则调用DefaultAdvisorAdapterRegistry的三个

AdvisorAdapter将Advsor转换成MethodInterceptor

DefaultAdvisorChainFactory类生成动态拦截器链的代码:

//DefaultAdvisorChainFactory,根据增强获取 Interceptor   
public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass) {
        List<Object> interceptorList = new ArrayList(config.getAdvisors().length);
        Class<?> actualClass = targetClass != null ? targetClass : method.getDeclaringClass();
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        AdvisorAdapterRegistry registry = GlobalAdvisorAdapterRegistry.getInstance();
        Advisor[] var8 = config.getAdvisors();
        int var9 = var8.length;

        for(int var10 = 0; var10 < var9; ++var10) {
            Advisor advisor = var8[var10];
            MethodInterceptor[] interceptors;

//如果是PointcutAdvisor
            if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {

//DefaultAdvisorAdapterRegistry的getInterceptors(Advisor advisor)获取MethodInterceptor
//在该方法里面就用到了AdvisorAdapter的getInterceptor()方法将Advice转换成对应的MethodInterceptor,例如MethodBeforeAdvie(前置增强)会通过MethodBeforeAdviceAdapter的
getInterceptor(Advisor)方法转换成MethodBeforeAdviceInterceptor类型的MethodInterceptor

                    interceptors = registry.getInterceptors(advisor);
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                            MethodInterceptor[] var15 = interceptors;
                            int var16 = interceptors.length;

                            for(int var17 = 0; var17 < var16; ++var17) {
                                MethodInterceptor interceptor = var15[var17];
                                interceptorList.add(new InterceptorAndDynamicMethodMatcher(interceptor, mm));
                            }
                        } else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            } else if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor)advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            } else {
                Interceptor[] interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }

 例如:编写一个自定义MyAdvice实现和MethodBeforeAdvice(前置通知)的功能

1:自定义Advice

package springAop;

import org.aopalliance.aop.Advice;

//自定义切面接口
public interface MyAdive extends Advice {
    public void zdyAdvice();
}


//切面实现类

public class MyAdviceImp implements MyAdive {
    public void zdyAdvice(){
        System.out.println("自定義切面");
    }
}

2:编写MyAdvisorAdapter实现AdvisorAdapter并重写以下两个方法

package springAop;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.framework.adapter.AdvisorAdapter;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;

/**
 * 自定义实现类实现AdvisorAdapter ,并且还要将该类通过DefaultAdvisorAdapterRegistry的registerAdvisorAdapter方法添加
 *      DefaultAdvisorAdapterRegistry advisorAdapterRegistry = new DefaultAdvisorAdapterRegistry();
 *         advisorAdapterRegistry.registerAdvisorAdapter(new MyAdvisorAdapter());
 */
public class MyAdvisorAdapter implements AdvisorAdapter {

    @Override
    public boolean supportsAdvice(Advice advice) {
        return advice instanceof MyAdive;
    }

    @Override
    public MethodInterceptor getInterceptor(Advisor advisor) {
        MyMethodInterceptor myMethodInterceptor = new MyMethodInterceptor((MyAdive) advisor.getAdvice());
        return myMethodInterceptor;
    }
}

3:编写 MethodInterceptor 接口的实现类MyMethodInterceptor,以便MyAdvisorAdapter 将MyAdive转换成MethodInterceptor,从而使用代理对象执行目标方法是获取动态Interceptor时,

this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass),将自定义增强逻辑放入增强链中

package springAop;

import org.aopalliance.aop.Advice;
import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;

/**
 * 自定义MethodInterceptor实现类,目的是将自定义的增强逻辑和目标方法进行关联调用
 */
public class MyMethodInterceptor implements MethodInterceptor {
    public MyAdive adive;
    public MyMethodInterceptor(MyAdive advice){
        this.adive = advice;
    }
    @Override
    public Object invoke(MethodInvocation methodInvocation) throws Throwable {
        Object result =methodInvocation.proceed();
        adive.zdyAdvice();
        return result;
    }
}

4:配置ProxyFactoryBean:这里采用配置类的方式:

package config;

import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import springAop.MyAdviceImp;
import springAop.MyAdvisorAdapter;
import springAop.MyDefaultAdvisorChainFactory;
import springAop.TestAop;

@Configuration
@ImportResource("classpath:bean.xml")
public class ConfigurationClass {
    @Bean
    public ProxyFactoryBean proxyFactoryBean(){
        ProxyFactoryBean pf = new ProxyFactoryBean();
        //设置目标类
        pf.setTarget(new TestAop());
        //以类的方式进行代理,实际上就是告诉AopFactory选用CGLib代理
        pf.setProxyTargetClass(true);
        //设置增强(这里是自定义增强)
        pf.addAdvice(new MyAdviceImp());
        DefaultAdvisorAdapterRegistry advisorAdapterRegistry = new DefaultAdvisorAdapterRegistry();
        //将我们的AdvisorAdapter放入DefaultAdvisorAdapterRegistry,以便在DefaultAdvisorAdapterRegistry 的
        // Advisor wrap(Object adviceObject)方法[将Advice封装成Advisor]中利用AdvisorAdapter的supportsAdvice()判断是否支持当前Advice
        advisorAdapterRegistry.registerAdvisorAdapter(new MyAdvisorAdapter());
        pf.setAdvisorAdapterRegistry(advisorAdapterRegistry);
        return pf;
    }
}

5:测试类:

    @Test
    public void Test_自定义Advice实现MethodBeforeAdvice() {
        TestAop aop = (TestAop) applicationContext.getBean("proxyFactoryBean");
        System.out.println(aop.add(1, 2));
    }

运行结果: 

 所以,这里我们需要自定义一个实现类实现org.springframework.aop.framework.AdvisorChainFactory接口,并实现其方法

AdvisorChainFactory源码:

package org.springframework.aop.framework;

import java.lang.reflect.Method;
import java.util.List;

public interface AdvisorChainFactory {
    List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised var1, Method var2, Class<?> var3);
}

这里为了偷懒我就直接继承他的实现类也就是DefaultAdvisorChainFactory类,并重写其getInterceptorsAndDynamicInterceptionAdvice方法

package springAop;

import org.aopalliance.intercept.Interceptor;
import org.aopalliance.intercept.MethodInterceptor;
import org.springframework.aop.Advisor;
import org.springframework.aop.IntroductionAdvisor;
import org.springframework.aop.MethodMatcher;
import org.springframework.aop.PointcutAdvisor;
import org.springframework.aop.framework.Advised;
import org.springframework.aop.framework.DefaultAdvisorChainFactory;
import org.springframework.aop.framework.adapter.AdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry;
import org.springframework.aop.framework.adapter.GlobalAdvisorAdapterRegistry;
import org.springframework.aop.support.MethodMatchers;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * 正常来说应该实现AdvisorChainFactory接口的,这里为了省事直接继承了DefaultAdvisorChainFactory接口,并将
 * getInterceptorsAndDynamicInterceptionAdvice()方法重写,将我们自定义的MyAdvisorAdapter放入DefaultAdvisorAdapterRegistry,
 * 这样在下面通过 registry.getInterceptors(advisor);获取MethodInterceptor是,当处理到我们自定义的MyAdvice时就不会提示类型错误
 */
public class MyDefaultAdvisorChainFactory extends DefaultAdvisorChainFactory {

    @Override
    public List<Object> getInterceptorsAndDynamicInterceptionAdvice(Advised config, Method method, Class<?> targetClass) {
        List<Object> interceptorList = new ArrayList(config.getAdvisors().length);
        Class<?> actualClass = targetClass != null ? targetClass : method.getDeclaringClass();
        boolean hasIntroductions = hasMatchingIntroductions(config, actualClass);
        AdvisorAdapterRegistry registry = new DefaultAdvisorAdapterRegistry();
        registry.registerAdvisorAdapter(new MyAdvisorAdapter());
        Advisor[] var8 = config.getAdvisors();
        int var9 = var8.length;

        for(int var10 = 0; var10 < var9; ++var10) {
            Advisor advisor = var8[var10];
            MethodInterceptor[] interceptors;
            if (advisor instanceof PointcutAdvisor) {
                PointcutAdvisor pointcutAdvisor = (PointcutAdvisor)advisor;
                if (config.isPreFiltered() || pointcutAdvisor.getPointcut().getClassFilter().matches(actualClass)) {
                    interceptors = registry.getInterceptors(advisor);
                    MethodMatcher mm = pointcutAdvisor.getPointcut().getMethodMatcher();
                    if (MethodMatchers.matches(mm, method, actualClass, hasIntroductions)) {
                        if (mm.isRuntime()) {
                        } else {
                            interceptorList.addAll(Arrays.asList(interceptors));
                        }
                    }
                }
            } else if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor)advisor;
                if (config.isPreFiltered() || ia.getClassFilter().matches(actualClass)) {
                    interceptors = registry.getInterceptors(advisor);
                    interceptorList.addAll(Arrays.asList(interceptors));
                }
            } else {
                interceptors = registry.getInterceptors(advisor);
                interceptorList.addAll(Arrays.asList(interceptors));
            }
        }

        return interceptorList;
    }

    private static boolean hasMatchingIntroductions(Advised config, Class<?> actualClass) {
        for(int i = 0; i < config.getAdvisors().length; ++i) {
            Advisor advisor = config.getAdvisors()[i];
            if (advisor instanceof IntroductionAdvisor) {
                IntroductionAdvisor ia = (IntroductionAdvisor)advisor;
                if (ia.getClassFilter().matches(actualClass)) {
                    return true;
                }
            }
        }

        return false;
    }
}

然后将MyDefaultAdvisorChainFactory 通过

pf.setAdvisorChainFactory(new MyDefaultAdvisorChainFactory());方法添加
package config;

import org.springframework.aop.Advisor;
import org.springframework.aop.framework.ProxyFactoryBean;
import org.springframework.aop.framework.adapter.DefaultAdvisorAdapterRegistry;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
import springAop.MyAdviceImp;
import springAop.MyAdvisorAdapter;
import springAop.MyDefaultAdvisorChainFactory;
import springAop.TestAop;

@Configuration
@ImportResource("classpath:bean.xml")
public class ConfigurationClass {
    @Bean
    public ProxyFactoryBean proxyFactoryBean(){
        ProxyFactoryBean pf = new ProxyFactoryBean();
        //设置目标类
        pf.setTarget(new TestAop());
        //以类的方式进行代理,实际上就是告诉AopFactory选用CGLib代理
        pf.setProxyTargetClass(true);
        //设置增强(这里是自定义增强)
        pf.addAdvice(new MyAdviceImp());
        DefaultAdvisorAdapterRegistry advisorAdapterRegistry = new DefaultAdvisorAdapterRegistry();
        //将我们的AdvisorAdapter放入DefaultAdvisorAdapterRegistry,以便在DefaultAdvisorAdapterRegistry 的
        // Advisor wrap(Object adviceObject)方法[将Advice封装成Advisor]中利用AdvisorAdapter的supportsAdvice方法判断是否支持当前Advice
        advisorAdapterRegistry.registerAdvisorAdapter(new MyAdvisorAdapter());
        //将切面适配注册器放入ProxyFactoryBean
        pf.setAdvisorAdapterRegistry(advisorAdapterRegistry);
        
        
        //将切面链生成工厂放入ProxyFactoryBean
        pf.setAdvisorChainFactory(new MyDefaultAdvisorChainFactory());
        return pf;
    }
}

运行结果

 虽然上面的场景一般很少使用,但是做这个的目的只是为了加深对代理的理解,明白如何生成代理类,并且ProxyFactoryBean支持的切面类型,切面最终会被转换成Interceptor chain链。以及

JdkDynamicAopProxy  的定义和处理原理:类似JDK动态代理也是实现InvocationHandler,并实现invoke()

final class JdkDynamicAopProxy implements AopProxy, InvocationHandler, Serializable 

JdkDynamicAopProxy  的invoke中会获取所有的增强

List<Object> chain = this.advised.getInterceptorsAndDynamicInterceptionAdvice(method, targetClass);

CglibAopProxy代理实际和Cglib代理原理一样,定义了

private static class DynamicUnadvisedExposedInterceptor implements MethodInterceptor, Serializable
private static class FixedChainStaticTargetInterceptor implements MethodInterceptor, Serializable 
private static class DynamicUnadvisedInterceptor implements MethodInterceptor, Serializable
private static class StaticUnadvisedExposedInterceptor implements MethodInterceptor, Serializable
private static class StaticUnadvisedInterceptor implements MethodInterceptor, Serializable
private static class HashCodeInterceptor implements MethodInterceptor, Serializable
private static class EqualsInterceptor implements MethodInterceptor, Serializable

等org.springframework.cglib.proxy.MethodInterceptor实现类

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值