静态代理、动态代理(JDK动态代理,Cglib动态代理)(3)

代理对象:ProxyFactory


package com.cglib;

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 target;//维护一个目标对象
    public ProxyFactory(Object target) {
        this.target = target;
    }
    
    //为目标对象生成代理对象
    public Object getProxyInstance() {
        //工具类
        Enhancer en = new Enhancer();
        //设置父类
        en.setSuperclass(target.getClass());
        //设置回调函数
        en.setCallback(this);
        //创建子类对象代理
        return en.create();
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("开启事务");
        // 执行目标对象的方法
        Object returnValue = method.invoke(target, args);
        System.out.println("关闭事务");
        return null;
    }
}


测试类:TestProxy



package com.cglib;

import org.junit.Test;

public class TestProxy {

    @Test
    public void testCglibProxy(){
        //目标对象
        UserDao target = new UserDao();
        System.out.println(target.getClass());
        //代理对象
        UserDao proxy = (UserDao) new ProxyFactory(target).getProxyInstance();
        System.out.println(proxy.getClass());
        //执行代理对象方法
        proxy.save();
    }
}


输出结果


class com.cglib.UserDao
class com.cglib.UserDao$$EnhancerByCGLIB$$552188b6
开启事务
保存数据
关闭事务


五、总结


静态代理实现较简单,只要代理对象对目标对象进行包装,即可实现增强功能,但静态代理只能为一个目标对象服务,如果目标对象过多,则会产生很多代理类。


JDK动态代理需要目标对象实现业务接口,代理类只需实现InvocationHandler接口。

动态代理生成的类为 lass com.sun.proxy.$Proxy4,cglib代理生成的类为class com.cglib.UserDao


EnhancerByCGLIB


EnhancerByCGLIB


552188b6。


静态代理在编译时产生class字节码文件,可以直接使用,效率高。


动态代理必须实现InvocationHandler接口,通过反射代理方法,比较消耗系统性能,但可以减少代理类的数量,使用更灵活。


cglib代理无需实现接口,通过生成类字节码实现代理,比反射稍快,不存在性能问题,但cglib会继承目标对象,需要重写方法,所以目标对象不能为final类。

六、静态代理与动态代理的区别


静态代理:硬编码、手动注入,手动拿到目标对象的引用,手动调用代理目标对象的方法

动态代理:具有更强的扩展性,自动注入,自动生成一个新的类(同一个继承体系)


特征: 拿到代理目标对象的引用,实现功能增强


七、JDK动态代理生成$Proxy0.java对象的步骤

1、动态生成源码.java文件

2、Java文件输出到磁盘,保存到P r o x y 0. j a v a 3 、 把 . j a v a 文 件 编 译 为 Proxy0.java 3、把.java文件编译为Proxy0.java3、把.java文件编译为Proxy0.class文件

4、把生成.class文件加载到JVM中

5、返回新的代理对象


Java三种代理模式:静态代理、动态代理和cglib代理


上一篇:《嵌入式Linux与物联网软件开发——C语言内核深度解析》一2.5 位运算实战演练1


下一篇:RestFaces提供了对JSF的书签支持