笔记【Jdk的Proxy与CGLib的理解】

代理与动态代理的概念

代理关系示图:
在这里插入图片描述
代理关系类图:
在这里插入图片描述

注:由上图可见,代理对象与代理类之间是实现了同接口的不同类,互相之间不存在继承关系而是组合关系(亦可以理解为类图中的“委托”)。至于代理与动态代理的区别,可以简单理解为代理类的生成方式不同而已。
静态代理:代理类由手动编码生成,缺点是不够灵活。
动态代理:可以采用Jdk提供Proxy.newPorxyInstance(…)运行时动态生产(一些基于接口的三方组件就是这种方式,例如:mybatis、feigen等)。

Proxy与CGLib的区别

JdkProxy的使用:

public class ProxyTest {

    @Test
    public void test1() {
        JdkTestA jdkTestA = new JdkTestA();
        IJdkTest jdkTest = (IJdkTest) Proxy.newProxyInstance(jdkTestA.getClass().getClassLoader(), JdkTestA.class.getInterfaces(), new InvocationHandler() {
            @Override
            public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                return method.invoke(jdkTestA, args);
            }
        });
        System.out.println(jdkTest.getClass().getName());
        System.out.println(jdkTest.greeting());
    }
}

CGLib的使用(原理此处暂时略过,涉及到字节码修改的东西):

public class MyProxyTestA {

    public void greeting() {
        System.out.println("my cglib greeting !!!");
    }

}

public class CglibTest {

    @Test
    public void test1() {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(MyProxyTestA.class);
        enhancer.setNamingPolicy(new DefaultNamingPolicy() {
            @Override
            protected String getTag() {
                return "ByZanghCGLIB";
            }
        });
        enhancer.setCallback(new MethodInterceptor() {
            @Override
            public Object intercept(Object obj, Method method, Object[] args, MethodProxy methodProxy)
                    throws Throwable {
                System.out.println("before,is inherit=" + (obj instanceof MyProxyTestA));
                Object res = methodProxy.invokeSuper(obj, args);
                System.out.println("after");
                return res;
            }
        });
        MyProxyTestA testAWithCglib = (MyProxyTestA) enhancer.create();
        System.out.println(testAWithCglib.getClass().getName() + ",id=");
        testAWithCglib.greeting();
    }

}

输出结果

org.thinking.spring.proxy.cglib.MyProxyTestA$$EnhancerByZanghCGLIB$$c0dbde28,id=
before,is inherit=true
my cglib greeting !!!
after

注1:由日志中inherit=true可见CGLib生成的代理类和代理对象是存在继承关系的。其实也由类名Enhancer(增强器)而非Proxy可以推测CGLib是通过继承后,重写方法实现对目标方法的控制的。严格来讲CGLib不能叫代理,这也是他和JdkProxy本质上的区别。
注2:因为是继承方式则CGLib不需要像JdkProxy那样需要代理目标存在接口。使用限制更少,在Spring中通常作为JdkProxy的备选方案(JdkProxy的效率随着jdk版本迭代性能越来越好)。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值