最近在研究RPC框架,避免不了的就是在RPC调用中使用最多的则是动态代理的机制了,基于此,我们先来研究一下JDK动态代理

我们先来尝试着编写一下JDK动态代理的代码

1. 由于JDK动态代理是基于接口的,所以不免需要先编写一个接口,并声明一个getHello方法

package cn.lonecloud.study.service;

import cn.lonecloud.study.dto.HelloDto;

/**
* @author lonecloud
* @version v1.0
* @Package cn.lonecloud.study
* @Description: TODO
* @date 2018/6/8下午4:36
*/
public interface HelloService { HelloDto getHello(String name);
}

2. 有了接口,肯定是需要实现类,并将getHello方法给予实现

package cn.lonecloud.study;

import cn.lonecloud.study.dto.HelloDto;
import cn.lonecloud.study.service.HelloService; /**
* @author lonecloud
* @version v1.0
* @Package cn.lonecloud.study
* @Description: TODO
* @date 2018/6/8下午11:35
*/
public class HelloImpl implements HelloService {
@Override
public HelloDto getHello(String name) {
return new HelloDto();
}
}  

这两个硬性条件有了,则我们来编写动态代理类了

1. 首先我们先来了解两个API:

  1. public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h):该类用于创建动态代理类的实例,

    1. loader:类的类加载器:一般用户类为AppClassLoader,可通过类名.class.getClassLoader()获得

    2. interfaces:接口数组,前面我们说过,jdk动态代理是基于接口来实现的,所以这个参数就是用来传递接口数组啦

    3. h:用于具体实现Handler,也就是这里执行相关的主要业务逻辑的地方了

  2. InvocationHandler:该接口用于实现动态代理类的相关业务逻辑

    1. 通常需要使用动态代理的话必须实现该接口,并重写其里面的invoke方法。

    2. invoke(Object proxy, Method method, Object[] args)throws Throwable; 

      1. proxy:代理类对象

      2. method:执行的方法

      3. args:相关的参数

编写相关的代理类

package cn.lonecloud.study;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy; /**
* @author lonecloud
* @version v1.0
* @Package cn.lonecloud.study
* @Description: TODO
* @date 2018/6/8下午11:23
*/
public class ProxyDemo {
//定义实现类对象
Object target;
//构造函数
public ProxyDemo(Object target) {
this.target = target;
}
//获取实现类方法
@SuppressWarnings("unchecked")
public <T> T getProxy(Class<T> clazz){
//获取代理实例
return(T) Proxy.newProxyInstance(clazz.getClassLoader(),new Class[]{clazz}, (proxy, method, args) -> {
System.out.println(method.getName());
//执行代理对象
return method.invoke(target,args);
});
}
}

  clazz.getClassLoader()获取的是类加载器,第二个参数创建了一个Class[]数组对象,由于传递过来的clazz为接口,所以可以这样写

执行:

        HelloService proxy1 = new ProxyDemo(new HelloImpl()).getProxy(HelloService.class);
HelloDto demo = proxy1.getHello("demo");

  该JDK动态代理的实现基本上就完成了,下一篇文章我们来看一下,jdk动态代理生产的字节码文件究竟是什么个样子

深挖JDK动态代理(二):JDK动态生成后的字节码分析

深挖JDK动态代理(一)的更多相关文章

  1. 深挖JDK动态代理(二):JDK动态生成后的字节码分析

    接上一篇文章深挖JDK动态代理(一)我们来分析一下JDK生成动态的代理类究竟是个什么东西 1. 将生成的代理类编程一个class文件,通过以下方法 public static void transCl ...

  2. JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析

    通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...

  3. JDK动态代理实例

    最近看<深入浅出MyBatis技术原理与实战>这本书时,里面讲到Mapper接口的内部实现是通过JDK动态代理生成实现类,联想到之前看<SPRING技术内幕>这本书里也常常提到 ...

  4. JDK动态代理

    一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...

  5. 静态代理和利用反射形成的动态代理(JDK动态代理)

    代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...

  6. Spring中的JDK动态代理

    Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...

  7. AOP学习心得&jdk动态代理与cglib比较

    什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...

  8. JDK动态代理的实现原理

    学习JDK动态代理,从源码层次来理解其实现原理参考:http://blog.csdn.net/jiankunking/article/details/52143504

  9. Java中的JDK动态代理

    所谓代理,其实就是相当于一个中间人,当客户端需要服务端的服务时,不是客户直接去找服务,而是客户先去找代理,告诉代理需要什么服务,然后代理再去服务端找服务,最后将结果返回给客户. 在日常生活中,就拿买火 ...

随机推荐

  1. md5加密通过URL传给后台

    首先要把你要用的md5库引入 这个技术其实挺简单的,咋们直接贴上代码(这个是项目上的) sign = hex_md5("type="+type&"userId=& ...

  2. 3 The simple past

    1 许多动词通过在原型之后添加-ed 构成一般过去式. 其他动词有不规则的过去式,使用一般过去式的时间词语出现在句首或者句尾 The company grew from 400 to 5,000 pe ...

  3. 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序

    题目: 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序 public static int maxGap(int nums[]) { if ( ...

  4. 【转】使用 lsof 查找打开的文件

      在 UNIX® 环境中,文件无处不在,这便产生了一句格言:“任何事物都是文件”.通过文件不仅仅可以访问常规数据,通常还可以访问网络连接和硬件.在有些情况下,当您使用 ls 请求目录清单时,将出现相 ...

  5. 解决mybatis generator警告Cannot obtain primary key information from the database, generated objects may be incomplete

    使用 mybatis generator 生成pojo.dao.mapper时 经常出现 Cannot obtain primary key information from the database ...

  6. easyui combobox 在datagrid中动态加载数据

    场景:datagrid 中用编辑框修改数据,有一个列使用的combobox  在可编辑的时候需要动态绑定数据,这个数据是在根据其他条件可变的 思路:在每次开启编辑框的时候动态绑定数据, datagri ...

  7. 4.namespace

    命名空间( namespace)是 Linux 内核的一个强大特性,为容器虚拟化的实现带来极大便 利. 利用这一特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在 独立的操作系统环境 ...

  8. Ubuntu下安装tomcat

    下面记录了Ubuntu 16.04下安装Tomcat 8.5.9的过程步骤. 1.到官网下载tomcat8.5.9,选择格式为tar.gz.2.通过ftp将下载的tomcat8.5.9压缩包上传到ub ...

  9. Python中数字之间的进制转换

    Python中的数据转换 在python中可以通过内置方法进行相应的进制转换,但需记得转化成非十进制时,都会将数字转化成字符串 转化成二进制 a = 10 #声明数字,默认十进制 b = bin(a) ...

  10. kubernetes ceph-rbd挂载步骤 类型storageClass

    由于kubelet本身并不支持rbd的命令,所以需要添加一个kube系统插件: 下载插件 quay.io/external_storage/rbd-provisioner 下载地址: https:// ...