深挖JDK动态代理(一)
最近在研究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动态代理(一)的更多相关文章
- 深挖JDK动态代理(二):JDK动态生成后的字节码分析
接上一篇文章深挖JDK动态代理(一)我们来分析一下JDK生成动态的代理类究竟是个什么东西 1. 将生成的代理类编程一个class文件,通过以下方法 public static void transCl ...
- JDK动态代理[4]----ProxyGenerator生成代理类的字节码文件解析
通过前面几篇的分析,我们知道代理类是通过Proxy类的ProxyClassFactory工厂生成的,这个工厂类会去调用ProxyGenerator类的generateProxyClass()方法来生成 ...
- JDK动态代理实例
最近看<深入浅出MyBatis技术原理与实战>这本书时,里面讲到Mapper接口的内部实现是通过JDK动态代理生成实现类,联想到之前看<SPRING技术内幕>这本书里也常常提到 ...
- JDK动态代理
一.基本概念 1.什么是代理? 在阐述JDK动态代理之前,我们很有必要先来弄明白代理的概念.代理这个词本身并不是计算机专用术语,它是生活中一个常用的概念.这里引用维基百科上的一句话对代理进行定义: A ...
- 静态代理和利用反射形成的动态代理(JDK动态代理)
代理模式 代理模式的定义:为其他对象提供一种代理以控制对这个对象的访问.在某些情况下,一个对象不适合或者不能直接引用另一个对象,而代理对象可以在客户端和目标对象之间起到中介的作用. 静态代理 1.新建 ...
- Spring中的JDK动态代理
Spring中的JDK动态代理 在JDK1.3以后提供了动态代理的技术,允许开发者在运行期创建接口的代理实例.在Sun刚推出动态代理时,还很难想象它有多大的实际用途,现在动态代理是实现AOP的绝好底层 ...
- AOP学习心得&jdk动态代理与cglib比较
什么是AOP AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善.OOP引入 ...
- JDK动态代理的实现原理
学习JDK动态代理,从源码层次来理解其实现原理参考:http://blog.csdn.net/jiankunking/article/details/52143504
- Java中的JDK动态代理
所谓代理,其实就是相当于一个中间人,当客户端需要服务端的服务时,不是客户直接去找服务,而是客户先去找代理,告诉代理需要什么服务,然后代理再去服务端找服务,最后将结果返回给客户. 在日常生活中,就拿买火 ...
随机推荐
- md5加密通过URL传给后台
首先要把你要用的md5库引入 这个技术其实挺简单的,咋们直接贴上代码(这个是项目上的) sign = hex_md5("type="+type&"userId=& ...
- 3 The simple past
1 许多动词通过在原型之后添加-ed 构成一般过去式. 其他动词有不规则的过去式,使用一般过去式的时间词语出现在句首或者句尾 The company grew from 400 to 5,000 pe ...
- 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序
题目: 给定一个数组,求如果排序之后,相邻两数的最大差值,要求时间复杂度为O(N),且要求不能用非基于比较的排序 public static int maxGap(int nums[]) { if ( ...
- 【转】使用 lsof 查找打开的文件
在 UNIX® 环境中,文件无处不在,这便产生了一句格言:“任何事物都是文件”.通过文件不仅仅可以访问常规数据,通常还可以访问网络连接和硬件.在有些情况下,当您使用 ls 请求目录清单时,将出现相 ...
- 解决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 ...
- easyui combobox 在datagrid中动态加载数据
场景:datagrid 中用编辑框修改数据,有一个列使用的combobox 在可编辑的时候需要动态绑定数据,这个数据是在根据其他条件可变的 思路:在每次开启编辑框的时候动态绑定数据, datagri ...
- 4.namespace
命名空间( namespace)是 Linux 内核的一个强大特性,为容器虚拟化的实现带来极大便 利. 利用这一特性,每个容器都可以拥有自己单独的命名空间,运行在其中的应用都像是在 独立的操作系统环境 ...
- Ubuntu下安装tomcat
下面记录了Ubuntu 16.04下安装Tomcat 8.5.9的过程步骤. 1.到官网下载tomcat8.5.9,选择格式为tar.gz.2.通过ftp将下载的tomcat8.5.9压缩包上传到ub ...
- Python中数字之间的进制转换
Python中的数据转换 在python中可以通过内置方法进行相应的进制转换,但需记得转化成非十进制时,都会将数字转化成字符串 转化成二进制 a = 10 #声明数字,默认十进制 b = bin(a) ...
- kubernetes ceph-rbd挂载步骤 类型storageClass
由于kubelet本身并不支持rbd的命令,所以需要添加一个kube系统插件: 下载插件 quay.io/external_storage/rbd-provisioner 下载地址: https:// ...