JDK动态代理与CGlib动态代理小结

JDK动态代理与CGlib动态代理

  • 应用场景
  • 区别
    • JDK动态代理
    • CGlib动态代理

应用场景

比如进行日志记录、监控某个方法的运行时间、权限控制、事务管理 (调用方法前开启事务, 调用方法后提交关闭事务 )、缓存优化 (第一次调用查询数据库,将查询结果放入内存对象, 第二次调用, 直接从内存对象返回,不需要查询数据库 )等等,总的来说是执行目标方法前后都可以干一些其他的事情,在不改动目标方法的前提下将目标方法与其他操作实现解耦。

区别

如果目标类有实现接口则用JDK动态代理,如果目标类没有实现接口则用CGlib动态代理。

JDK动态代理

接口:

public interface PrepareWork {
    //打开电脑
    public void openCompare();

    //输入语言,开始撸代码
    public void LuCode(String language);
}

目标类:

public class RealWork implements PrepareWork {
    @Override
    public void openCompare() {
        System.out.println("open computer......!");
    }

    @Override
    public void LuCode(String language) {
        System.out.println("今天用" + language +"撸代码");
    }
}

代理工厂:

public class ProxyFactory {
    private Object object; // 目标对象

    public ProxyFactory(Object object) {
        this.object = object;
    }

    public Object getProxyInstance() {
        return Proxy.newProxyInstance(
                object.getClass().getClassLoader(),
                object.getClass().getInterfaces(), new InvocationHandler() {
                    // proxy:表示我们代理的真实对象
                    // method:表示调用真实对象中的某个方法的metode对象
                    // args:调用真实对象方法里所传的参数
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                        // TODO Auto-generated method stub
                        //在代理真实对象前我们可以添加一些自己的操作
                        System.out.println("调用方法前执行!");
                        //目标方法调用
                        Object obj = method.invoke(object, args);
                        System.out.println("方法执行完毕!");
                        return obj;
                    }
                });
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        // 1.要代理的真实对象
        RealWork prepareWork = new RealWork();//
        PrepareWork proxy = (PrepareWork) new ProxyFactory(prepareWork).getProxyInstance();
        proxy.openCompare();
        System.out.println("-----------------------------分隔符-----------------------------");
        proxy.LuCode("PAYTHON");
    }
}

结果:
JDK动态代理与CGlib动态代理小结_第1张图片

CGlib动态代理

目标类:

public class RealWork {
    //新增
    public void insertInf() {
        System.out.println("增加...");
    }
    //删除
    public void deleteInf() {
        System.out.println("删除...");
    }
    //修改
    public void updateInf() {
        System.out.println("修改...");
    }
    //查询
    public void selectInf() {
        System.out.println("查询...");
    }
}

代理工厂:

public class ProxyFactory {
    // 被代理对象
    private Object object;

    public ProxyFactory(Object object) {
        this.object = object;
    }

    public Enhancer getProxyInstance(){
        //创建cglib核心对象
        Enhancer enhancer = new Enhancer();
        //设置父类
        enhancer.setSuperclass(object.getClass());
        //设置回调
        enhancer.setCallback(new org.springframework.cglib.proxy.MethodInterceptor() {
        /**
         * 当你调用目标方法时,实质上是调用该方法
         * intercept四个参数:
         * proxy:代理对象
         * method:目标方法
         * args:目标方法的形参
         * methodProxy:代理方法
         */
        @Override
        public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
            // TODO Auto-generated method stub
            //在代理真实对象前我们可以添加一些自己的操作
            System.out.println("调用方法前执行!");
            //目标方法调用
            Object result = methodProxy.invokeSuper(proxy, args);
            System.out.println("方法执行完毕!");
            return result;
        }
        });
        return enhancer;
    }
}

测试:

public class Test {
    public static void main(String[] args) {
        RealWork realWork = new RealWork();
        //创建代理对象
        RealWork proxyObj = (RealWork) new ProxyFactory(realWork).getProxyInstance().create();
        proxyObj.insertInf();
        proxyObj.deleteInf();
        proxyObj.updateInf();
        proxyObj.deleteInf();
    }
}

结果:
JDK动态代理与CGlib动态代理小结_第2张图片

你可能感兴趣的:(java设计模式)