代理模式---Cglib动态代理

使用 CGLIB 生成动态代理,首先需要生成 Enhancer 类实例,并指定用于处理代理业务的回调类。

在 Enhancer.create() 方法中,会使用 DefaultGeneratorStrategy.Generate() 方法生成动态代理类的字节码,

并保存在 byte 数组中。接着使用 ReflectUtils.defineClass() 方法,通过反射,调用 ClassLoader.defineClass() 方法,

将字节码装载到 ClassLoader 中,完成类的加载。最后使用 ReflectUtils.newInstance() 方法,通过反射,生成动态类的实例,

并返回该实例。基本流程是根据指定的回调类生成 Class 字节码—通过 defineClass() 将字节码定义为类—使用反射机制生成该类的实例。

真实主题:

public class Cglib {

    void todo(){

        System.out.println("todo someThing....");
    }
}

代理类:

package com.infinitePossibilities.aop_proxy.cglibProxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;
import java.lang.reflect.Method;

public class CglibProxy implements MethodInterceptor {


    Object getCglibProxyInstance(){

        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(Cglib.class);
        enhancer.setCallback(this);

        return enhancer.create();
    }

    @Override
    public Object intercept(Object object, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {

        System.out.println("Before.....");

        methodProxy.invokeSuper(object,args);

        System.out.println("After.....");

        return null;
    }
}

测试:

package com.infinitePossibilities.aop_proxy.cglibProxy;

public class Test {

    /**
     * 优点:
     *
     * CGLIB通过继承的方式进行代理、无论目标对象没有没实现接口都可以代理,弥补了JDK动态代理的缺陷。
     *
     * 缺点:
     *
     * CGLib创建的动态代理对象性能比JDK创建的动态代理对象的性能高不少,但是CGLib在创建代理对象时
     *
     * 所花费的时间却比JDK多得多,所以对于单例的对象,因为无需频繁创建对象,用CGLib合适,
     *
     * 反之,使用JDK方式要更为合适一些。
     *
     * 由于CGLib由于是采用动态创建子类的方法,对于final方法,无法进行代理。
     *
     */
    public static void main(String[] args) {

        CglibProxy cglibProxy = new CglibProxy();

        Cglib cglib = (Cglib) cglibProxy.getCglibProxyInstance();

        cglib.todo();


    }

}
原文地址:https://www.cnblogs.com/lifan12589/p/14822331.html