读懂Dubbo源码必备知识点之三

    Dubbo中的代理模式:所谓代理模式,简单点说就是调用端不能直接引用某个服务,通过一个中介角色来间接调用这个服务,而这个中介就是充当
着代理的角色,去调用服务端的。
Java中的代理总体上分为两种:一种是静态代理,二种是动态代理
1、静态代理就很简单了,就是通过硬编码方式(不知道这样形容对不对)写一个实际存在的代理角色,去间接的调用服务方法。
2、动态代理是相对于静态代理而言,因为静态代理使用过程中都要产生一个代理角色,这明显是不科学的,因为在使用中会产生大理的代理类。
   因此,动态代理的优势就很明显了,在Java体系中,可以细分为两种动态代理,一种JDK的原生动态代理,另一种是基于CGLIB(Code Generation Library)方式的动态代理,区别就是JDK代理只能针对接口类代理,而CBLIB可以对具体类实现代理,单纯从效率上看,单例的对象似乎CGLIB会比JDK快一些,而对于final方法,无法进行代理。
这理要提一下:大量的使用CGLIB动态代理可能会导致虚拟机方法区溢出,因为会动态的产生class文件,可以用VisualVM观察一下,这个工作JDK中自带的哈。
JDK代理:这里面要用到InvocationHandler 接口,很简单里面只有一个方法,以及Proxy类,这个类是关键所在。
有一个思考题:为什么JDK代理只能对接口方式实现代理,呵呵,仔细看看还是很有意思的这里就不说了。
CGLIB方式:通俗讲,运用字节码技术创建一个类的子类,主要就是实现这个接口MethodInterceptor,里面只有一个方法,使用前先用Maven引入cglib包。
下面是举的例子:
public interface ProxyInterface {
    void sendEmail();
}
public class ProxyInterfaceImpl implements ProxyInterface {
    @Override
    public void sendEmail() {
        System.out.println("发到北京去!");
    }
}
public class RealProxy implements ProxyInterface {

    private ProxyInterface proxy;

    public RealProxy() {
        this.proxy = new ProxyInterfaceImpl();
    }

    @Override
    public void sendEmail() {
        System.out.println("同志你好!");
        proxy.sendEmail();
    }
}
public class DynamicProxy implements InvocationHandler {

    //对真实对象的引用
    private Object o;

    public DynamicProxy(Object o) {
        this.o = o;

    }

    @Override
    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        System.out.println("我也可以说:同志你好!");
        return method.invoke(o, args);
    }
}
public class CglibProxy implements MethodInterceptor {

    private Enhancer enhancer = new Enhancer();
    public Object getProxy(Class clazz){
        enhancer.setSuperclass(clazz);
        enhancer.setCallback(this);
        return enhancer.create();
    }
    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
        System.out.println("除了你们,我也可以说:同志你好");
        return proxy.invokeSuper(obj, args);
    }
}
public class TestMain {

    public static void main(String[] args) {
       /* 静态代理*/
        ProxyInterface proxy = new RealProxy();
        proxy.sendEmail();
       /* JDK动态代理*/
        DynamicProxy handler = new DynamicProxy(new ProxyInterfaceImpl());


        ProxyInterface proxyInterface = (ProxyInterface) Proxy.newProxyInstance(handler.getClass()
                        .getClassLoader(), new ProxyInterfaceImpl().getClass().getInterfaces(),
                handler);

        proxyInterface.sendEmail();
        /* CGLIB动态代理*/
        CglibProxy cglicbProxy = new CglibProxy();

        ProxyInterfaceImpl cglibImpl = (ProxyInterfaceImpl) cglicbProxy.getProxy(ProxyInterfaceImpl.class);
        cglibImpl.sendEmail();
    }
}
结果:
同志你好!
发到北京去!
我也可以说:同志你好!
发到北京去!
除了你们,我也可以说:同志你好!
发到北京去!


Process finished with exit code 0

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值