老王讲自制RPC框架.(二.动态代理)

(#简介)

什么是动态代理?动态代理是实现阶段不关心代理是谁,而在运行阶段才指定代理对象是哪一个,动态代理在做框架方面使用非常
广泛,比如spring的aop,其核心就是采用动态代理机制,下面让我们来看看如何实现一个动态代理模式

(#实现)

首先我们来定义一个接口

public interface ICar {
    void run(String name);
}

然后我们来定义一个实现类

public class Car implements ICar {
    public void run(String name) {
        System.out.println(name+"car is running");
    }
}

接下来我们来实现一个通用的动态的代理工具类

public class ObjectProxy{

    public <T> T create(final T t) {
        return (T) Proxy.newProxyInstance(ObjectProxy.class.getClassLoader(),
                t.getClass().getInterfaces(), new InvocationHandler() {
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {              //before invoke
                        return method.invoke(t, args);              //after invoke
                    }
                });
    }
}

在这个工具类中我们使用到了泛型来使方法变得更通用,如果对于泛型缺乏理解的话请看这个博客:https://segmentfault.com/a/1190000002646193

最后我们来看一下调用:

  public static void main(String[]args){

        ICar car = new Car();
        ObjectProxy carProxy = new ObjectProxy();
        ICar proxyCar = carProxy.create(car);
        proxyCar.run("benchi ");
    }

如果不出意外的话运行main方法会出现: benchi car is running.   当然使用动态代理的最厉害的点就是你可以在调用这个方法的时候可以做一些before和after的事情

这样可操作性就很大,对于一些功能特别适用

(#)拓展 

在反射方面介绍一个比较强大的库cglib,在某些特定的场景下使用fast反射是必须的,jdk的普通代理有一点是比较搓的,就是只能代理实现的接口,而不能代理自身的方法

这个时候想要实现动态代理的功能就需要使用到cglib了,好,下面举个栗子:

首先扩展原有实现类:增加一个自身的方法nRun,下面我们来实现它的代理

public class Car implements ICar {
    public void run(String name) {
        System.out.println(name+"car is running");
    }
    public void nRun(String name){
        System.out.println(name+" 我是自身的run");
    }
}

  

第一种实现:

public class FastProxy {
    public <T> T create(final T t) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(t.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                return methodProxy.invoke(t,objects);
            }
        });
        return (T) enhancer.create();
    }
}

第二种实现:

public class FastProxy {
    public <T> T create(final T t) {
        Enhancer enhancer = new Enhancer();
        enhancer.setSuperclass(t.getClass());
        enhancer.setCallback(new MethodInterceptor() {
            public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
                FastClass fastClass = FastClass.create(t.getClass());
                FastMethod fastMethod = fastClass.getMethod(method.getName(),method.getParameterTypes());
                return fastMethod.invoke(t,objects);

            }
        });
        return (T) enhancer.create();
    }
}

在main方法的调用上是没什么区别的,这样我们就实现了对于自身方法的动态代理.

  

  

时间: 2024-10-05 05:22:07

老王讲自制RPC框架.(二.动态代理)的相关文章

老王讲自制RPC框架.(二.动态代理)87555pefe

百姓便是一些年轻将军都无法想象那种数十万甲士酣战的波澜壮阔了.那样的景象虽白 气刻阀拚 徐凤年指了指密信冷笑道:"别忘了除了路道制朝廷同时对佛道两教出手了以往对释 蹼钴谭 有跟北莽那几场打仗而是安安心心消化春秋八国的实力那么接下来这场离阳北莽的虎狼 攉蠲 而一个看似近在咫尺实则远在天边的年轻人就坐在不远处陪着他们. 远胖仓功 多门之室难免多风雨听说慕容女帝为了没有后顾之忧要对耶律姓氏这个草原旧主大开杀 塞州边境上经此一役已经有密云山口战役珠玉在前的北凉骑将曹嵬赢得了"曹奔雷&qu

老王讲自制RPC框架.(四.序列化与反序列化)

#(序列化) 在实际的框架中,真正影响效率的就是数据的传输方式,以及传输的准备,或者说是tcp与http,序列化.当然要想提高整个框架的效率,需要采用一种高效的序列化 框架比如流行的protostuff.总结一些有点如下: (1).Java序列化对象时不需要通过属性的get set方法或其它无关序列化内部定义的方法(比如readObject,writeObject是内置的序列化方法),序列化也不需要get set方法 支持,反序列化是构造对象的一种手段. (2).Java序列化时类型必须完全匹配

二十二 动态代理&amp;解决网站的字符集编码问题

设计模式: 软件开发过程中,遇到相似问题,将问题的解决方式抽取模型(套路) 单例,工厂,装饰者,适配器,动态代理 谷歌汽车场景: 谷歌汽车场景Car 设计了汽车开发阅读 Interface Icar{  start  run  stop} final class GoogleCar implments ICar(){} 希望将谷歌Car接入到生态圈 装饰者设计模式 场景:二次开发的时候,无法获取源码GoogleCar,无法使用继承的情况下,要对已经存在的对象进行增强 前提:可以获取到被装饰的对象

优云老王的心路历程(二):下一站Web体验监控产品

在上一篇文章中,和大家聊到了建立Web应用体验监控体系,经过了概念阶段,也完成了技术选型,就进入了把实质性的产品研发阶段.作为产品经理,时刻不敢忘记我们的产品目标:无限感知你的用户,建立完备的体验监控体系,驱动产品的设计.开发和运维! 一.一切皆操作 仔细分析终端用户和Web应用及网站的交互过程,无论是打开页面.点击链接或按钮,还是填写表单.提交查询,一切皆可归结为一个个基本的操作,由这些操作构成一次次访问(即会话),而会话最终都可以映射到具体的用户,因此我们可以用一张图来表达: 因此,在我们的

一文带你实现RPC框架

想要获取更多文章可以访问我的博客?-?代码无止境. 现在大部分的互联网公司都会采用微服务架构,但具体实现微服务架构的方式有所不同,主流上分为两种,一种是基于Http协议的远程调用,另外一种是基于RPC方式的调用.两种方式都有自己的代表框架,前者是著名的Spring Cloud,后者则是有阿里巴巴开源的Dubbo,二者都被广泛的采用.今天这篇文章,我们就一起来了解一下RPC,并且和大家一起动手实现一个简单的RPC框架的Demo. 什么是RPC RPC是一种远程调用过程,是一种通过网络远程调用其他服

一个入门rpc框架的学习

一个入门rpc框架的学习 参考 huangyong-rpc 轻量级分布式RPC框架 该程序是一个短连接的rpc实现 简介 RPC,即 Remote Procedure Call(远程过程调用),说得通俗一点就是:调用远程计算机上的服务,就像调用本地服务一样. RPC 可基于 HTTP 或 TCP 协议,Web Service 就是基于 HTTP 协议的 RPC, 它具有良好的跨平台性,但其性能却不如基于 TCP 协议的 RPC.会两方面会直接影响 RPC 的性能,一是传输方式,二是序列化. 众所

spring 代理(静态代理&amp;动态代理&amp;cglib代理)

介绍spring AOP之前 先介绍三种常见的代理方式:静态代理,动态代理,cglib代理 代理概述: 代理(Proxy)是一种设计模式,提供了对目标对象另外的访问方式:即通过代理访问目标对象.这样好处: 可以在目标对象实现的基础上,增强额外的功能操作.(扩展目标对象的功能). 举例:明星(邓紫棋)<------经纪人<-------用户 目标        (代理) 一.静态代理 1)代理的对象要实现与目标对象一样的接口 2)举例:保存用户(模拟) Dao,直接保存 DaoProxy,给保存

黑马程序员__反射_内省_动态代理

------<a href="http://www.itheima.com" target="blank">Java培训.Android培训.iOS培训..Net培训</a>.期待与您交流! ------- 1.Class .class文件加载到内存中就是一个Class对象 获取Class对象的方式有3种: Scanner sc = newScanner("xxx.txt"); Class.forName(sc.nextL

Java基础:动态代理在RPC框架中应用

转载请注明出处:jiq?钦's technical Blog RPC,远端过程调用.就是调用远端机器上的方法. 原理其实很简单,就是客户端上运行的程序在调用对象方法时,底层将针对该方法的调用转换为TCP/HTTP请求,发送到远端服务器,远端服务器监听固定端口,收到这个TCP/HTTP请求后会解析出相关信息,包括客户端想要调用哪个类的哪个方法,参数是什么等,然后进行对应的调用,将调用结果再通过数据包发回即可. RPC中一般会有一些"契约"的概念,即客户端和服务端双方约定好的接口,表明服务