Java下的两种代理

代理

JDK动态代理


// loader – the class loader to define the proxy class 类加载器
// interfaces – the list of interfaces for the proxy class to implement 类实现接口
// h – the invocation handler to dispatch method invocations to 调用方法前后执行的动作

public static Object newProxyInstance(ClassLoader loader,
                                          Class<?>[] interfaces,
                                          InvocationHandler h)
        throws IllegalArgumentException { ... }

public interface InvocationHandler {

        // return handler.invoke( proxy, method, args ) ;
    public Object invoke(Object proxy, Method method, Object[] args)
        throws Throwable;
}

CGLIB动态代理

CGLIB(Code Generation Library)是一个基于ASM的字节码生成库,它允许我们在运行时对字节码进行修改和动态生成。CGLIB 通过继承方式实现代理。很多知名的开源框架都使用到了CGLIB, 例如 Spring 中的 AOP 模块中:如果目标对象实现了接口,则默认采用 JDK 动态代理,否则采用 CGLIB 动态代理。

/**
 * obj :被代理的对象(需要增强的对象)
 * method :被拦截的方法(需要增强的方法)
 * args :方法入参
 * methodProxy :用于调用原始方法
 */
public interface MethodInterceptor extends Callback {
    // 拦截被代理类中的方法
    public Object intercept(Object obj, java.lang.reflect.Method method, Object[] args,
                               MethodProxy proxy) throws Throwable;
}

public class CglibProxyFactory {

    public static Object getProxy(Class<?> clazz) {
                String path = "/tmp";
        // 该设置用于输出cglib动态代理产生的类
        System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY, path);

        // 创建动态代理增强类
        Enhancer enhancer = new Enhancer();
        // 设置类加载器
        enhancer.setClassLoader(clazz.getClassLoader());
        // 设置被代理类
        enhancer.setSuperclass(clazz);
        // 设置方法拦截器
        enhancer.setCallback(new DebugMethodInterceptor());
        // 创建代理类
        return enhancer.create();
    }
}

两种代理方式的对比

JDK代理

  • 大部分情况下效率比GCLIB代理高
  • 只能代理实现了接口的类

CGLIB代理

  • 可代理的方法更多,没有接口的局限性
  • 不能代理声明为final的类和方法

代理失效的情况

  • JDK代理
    • 未在接口上的方法
  • CALIB代理
    • 声明为final的类或方法
  • 不走代理的情况
    • 类内部通过this调用
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容

  • 504b 0304 1400 0008 0800 4498 963d a6fa9ff3 9f41 1e00 a88...
    BossOx阅读 11,385评论 0 0
  • 504b 0304 1400 0008 0800 fa8c 963d 50740baa dffc 0e00 6cd...
    BossOx阅读 3,537评论 0 0
  • 夜莺2517阅读 127,757评论 1 9
  • 版本:ios 1.2.1 亮点: 1.app角标可以实时更新天气温度或选择空气质量,建议处女座就不要选了,不然老想...
    我就是沉沉阅读 6,951评论 1 6
  • 我是一名过去式的高三狗,很可悲,在这三年里我没有恋爱,看着同龄的小伙伴们一对儿一对儿的,我的心不好受。怎么说呢,高...
    小娘纸阅读 3,416评论 4 7