Spring的AOP动态代理有两种实现方式,JDK实现和CGLIB实现,那么两者有何种区别呢?
区别
JDK的动态代理主要是实现接口的方式,CGLIB主要是通过创建子类的方式,在父类的方法外进行操作。
- 如果类是接口的时候或者类是JDK创建的proxy类时使用的是JDK代理的
- 非接口类使用CGLib代理,或者配置注解中proxyTargetClass = true
两者的性能对比:

核心代码位置

JDK动态代理原理
JDK动态代理主要是通过,反射包中的Porxy类和InvokationHandler接口。它们结合在一起后可以创建动态代理类。Porxy类基于传递的参数创建动态代理类。InvokationHandler则用于激发动态代理类的方法。这个过程是在程序执行过程中动态生成与处理的,所以叫动态代理。
代码如下:
Porxy类
Porxy类提供了一个静态方法创建动态代理类。
public static Object newProxyInstance(ClassLoader loader,           
    Class<?>[] interfaces,                                      
    InvocationHandler h)
throws IllegalArgumentException
1、ClassLoader:ClassLoader会定义动态代理类,ClassLoader可以通过类或者接口获得,如果我们想通过接口获得,调用方法如下。
    Task.class.getClassLoader()
如果通过类来获得,加入我们有一个类TaskImpl实现了Task接口,我们有个TaskImpl的对象ob,然后ClassLoader获取方法如下
    ob.getClassLoader()
2、 Class<?>[] interfaces:动态代理类需要实现的接口
3、InvocationHandler:传递一个实现了InvokationHandler接口的类的实例
InvokationHandler
InvokationHandler是Java 反射包里面的一个接口。InvokationHandler通过用户类来实现,来激发一个动态代理类的方法。它只有一个方法:
public Object invoke(Object proxy, Method method, Object[] args)    throws Throwable;
1、Object:实现方法的代理对象 2、Method:代理实例激发的方法,Porxy参数中的接口方法 3、Object[]:传递给方法的一系列参数
实现
1、我们提供一个接口
package me.aihe;
public interface Task {
    void setData(String data);
    int getCalData(int x);
}
2、实现这个接口
package me.aihe;
public class TaskImpl implements Task {
    @Override
    public void setData(String data) {
        System.out.println(data+ " Data is saved");
    }
    @Override
    public int getCalData(int x) {
        return x * 10;
    }
}
3、定义自己的InvokationHandler类,并且实现InvokationHandler接口的Invoke方法
package me.aihe;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class MyInvokationHandler implements InvocationHandler {
    private Object obj;
    public MyInvokationHandler(Object object){
        this.obj = object;
    }
    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        Object result;
        if(method.getName().contains("get")){
            System.out.println("...get Method Executing...");
        }else{
            System.out.println("...set Method Executing...");
        }
        result = method.invoke(obj, args);
        return result;
    }
}
4、创建一个工厂类获取动态代理类:
package me.aihe;
import java.lang.reflect.Proxy;
public class ProxyFactory {
    public static Object newInstance(Object ob) {
        return Proxy.newProxyInstance(ob.getClass().getClassLoader(),
                new Class<?>[] { Task.class }, new MyInvokationHandler(ob));
    }
}
5、提供我们的测试类
package me.aihe;
public class Test {
    public static void main(String[] args) {
        Task task = (Task)ProxyFactory.newInstance(new TaskImpl());
        task.setData("Test");
        System.out.println("============");
        System.out.println(task.getCalData(5));
    }
}
看到程序的输出结果:
...set Method Executing...
Test Data is saved
============
...get Method Executing...
50
CGLIB代码案例
这里提供下使用方式。
1. 创建业务类
引入Maven:
<!-- https://mvnrepository.com/artifact/cglib/cglib -->
<dependency>
    <groupId>cglib</groupId>
    <artifactId>cglib</artifactId>
    <version>3.3.0</version>
</dependency>
package cglib.enhancer;
public class Hello {
    public String sayHello(boolean throwException) throws Exception {
        System.out.println("hello everyone!");
        if(throwException)
            throw new Exception("test exception");
        return "123";
    }
}
2. 实现MethodInterceptor接口
package cglib.enhancer;
import java.lang.reflect.Method;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class ProxyFactory implements MethodInterceptor {
     //要代理的原始对象
    private Object obj;
    public Object createProxy(Object target) {
        this.obj = target;
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(this.obj.getClass());// 设置代理目标
        enhancer.setCallback(this);// 设置回调
        enhancer.setClassLoader(target.getClass().getClassLoader());
        return enhancer.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        Object result = null;
        try {
            // 前置通知
            before();
            result = proxy.invokeSuper(obj, args);
            // 后置通知
            after();
        } catch (Exception e) {
            exception();
        }finally{
            beforeReturning();
        }
        return result;
    }
    private void before() {
        System.out.println("before method invoke");
    }
    private void after() {
        System.out.println("after method invoke");
    }
    private void exception() {
        System.out.println("method invoke exception");
    }
    private void beforeReturning() {
        System.out.println("before returning");
    }
}
3. 动态代理
package cglib.enhancer;
public class EnhancerTest {
    public static void main(String[] args) throws Exception {
        Hello hello = new Hello();
        ProxyFactory cglibProxy = new ProxyFactory();
        Hello proxy = (Hello) cglibProxy.createProxy(hello);
        String result=proxy.sayHello(true);
        System.out.println(result);
    }
}
4. 输出










