深度模拟java动态代理实现机制系类之二
这次我们要实现的是对任意接口,任意的方法进行特定的代理
这里不一样的只有Proxy类,要实现对所有方法进行代理,那么重点就在于获得接口的所有方法
import java.io.File;
import java.io.FileWriter;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader; import javax.tools.JavaCompiler;
import javax.tools.StandardJavaFileManager;
import javax.tools.ToolProvider;
import javax.tools.JavaCompiler.CompilationTask; //该类实现了对任意接口,任意方法的特定代理
public class ProxyG2 {
//产生新的动态代理类
public static Object newProxyInstance(Class intf) throws Exception{ //将接口当成参数传入,这样就可以代理实现了任意接口的类,而不仅是实现了Moveable接口
String methodsString = ""; //获得所有方法字符串
String rt = "\r\n"; Method[] methods = intf.getMethods();
for(Method m : methods){
methodsString += "@Override "+ rt+
"public void "+m.getName()+" (){"+"" +rt+
" long start = System.currentTimeMillis();"+rt+
" System.out.println(\"start time is \"+start);"+rt+
" t."+m.getName()+"();"+rt+
" long end = System.currentTimeMillis();"+rt+
" System.out.println(\"end time is \"+end);"+rt+
" System.out.println(\"time is \"+(end - start));"+rt+
"}"+rt;
} //将一下字符串动态编译,生成代理类
//实现方式有以下击中:jdk6.0 complier API;CGLib; ASM String src =
"public class TankTimeProxy implements " +intf.getName()+ "{"+rt+ //直接用intf,是调用toString方法,前会加入字符串 interface
" Moveable t;"+rt+ " public TankTimeProxy("+intf.getName()+" t) {"+rt+
" this.t = t;"+rt+
" }"+rt+ methodsString+
"}"; //进行编译
String fileName = "g:/src/TankTimeProxy.java";//放在指定的地方
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
//System.out.println(fileName);
fw.write(src); //写入内容 fw.flush();
fw.close(); //进行编译
//首先获得编译器
//compiler 为java编译器 javac
//获得编译器对象
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
//System.out.println(compiler.getClass().getName());//取得类名
//参数含义 (编译诊断,locale,charset)
//管理动态生成d文件
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null,null,null);//默认值
//根据参数获取多个java文件 返回java文件对象
Iterable units = fileManager.getJavaFileObjects(fileName); //“编译任务”对象
JavaCompiler.CompilationTask task = compiler.getTask(null,fileManager,null,null,null,units);
task.call();//调用
fileManager.close();
//System.out.println("***************************************"); //************以上过程获得了java文件源码,编译生成了java文件的class文件*******
//加载至内存,生成新对象
//Class.load(0 是加载path路径的class文件
//URLClassLoader是将硬盘中的class文件加载进入 //通过Url引入本地文件
URL[] urls = new URL[]{new URL("file:/"+"g:/src/")}; //访问本地文件 指定class文件存放的位置
//去指定路径寻找class文件
URLClassLoader urlClassLoader = new URLClassLoader(urls); Class c = urlClassLoader.loadClass("TankTimeProxy"); System.out.println(c); //执行
//c.newInstance(); 是调用空的构造方法 //获得构造方法
//根据java虚拟机,每一个构造方法也相当于一个对象
Constructor constructor = c.getConstructor(intf); //产生新对象
Object m = constructor.newInstance(new Tank()); //new Tank()为构造方法的参数 即被代理对象 //m.move(); return m;
}
}
深度模拟java动态代理实现机制系类之二的更多相关文章
- 深度模拟java动态代理实现机制系类之三
这里的内容就比较复杂了,要实现的是对任意的接口,对任意指定的方法,以及对任意指定的代理类型进行代理,就更真实的模拟出java虚拟机的动态代理机制 罗列一下这里涉及的类.接口之间的关系,方便大家学习.1 ...
- 深度模拟java动态代理实现机制系类之一
上一篇博客是最基本的动态代理原理的实现,因为其固定了接口,固定了代理方法,以及固定了代理的类型,接下来的博客系类将一步步渐入深度介绍java的动态代理的实现原理 ******************* ...
- 透过字节码生成审视Java动态代理运作机制
对于动态代理我想应该大家都不陌生,就是可以动态去代理实现某个接口的类来干一些我们自己想要的功能,但是在字节码层面它的表现是如何的呢?既然目前刚好在研究字节码相关的东东,有必要对其从字节码角度来审视一下 ...
- Java 动态代理机制分析及扩展
Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...
- [转]Java 动态代理机制分析及扩展
引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...
- Java 动态代理机制分析及扩展--转
http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...
- Java 动态代理机制分析及扩展,第 1 部分
Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...
- JAVA动态代理的全面深层理解
Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过 ...
- 一文读懂Java动态代理
作者 :潘潘 日期 :2020-11-22 事实上,对于很多Java编程人员来说,可能只需要达到从入门到上手的编程水准,就能很好的完成大部分研发工作.除非自己强主动获取,或者工作倒逼你学习,否则我们好 ...
随机推荐
- sudo: /etc/sudoers is mode 0640, should be 0440解决办法
ubuntu或者CentOS中,/etc/sudoer 的权限为 0440时才能正常使用,否则sudo命令就不能正常使用.出现类似:sudo: /etc/sudoers is mode 0640, s ...
- C#基础知识之方法重载总结
1.首先解释一下什么是方法重载? 方法重载是指在同一个类中方法同名,参数不同,调用时根据实参的形式,选择与他匹配的方法执行操作的一种技术. 这里所说的参数不同是指以下几种情况: ① 参数的类型 ...
- linux内核编译步骤
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- ant中调用外部ant任务的两种方法
国内私募机构九鼎控股打造APP,来就送 20元现金领取地址:http://jdb.jiudingcapital.com/phone.html内部邀请码:C8E245J (不写邀请码,没有现金送)国内私 ...
- Win7家庭普通版、家庭高级版、专业版、旗舰版版本差别
刚才我们发了一个大图片:<Windows7.Vista.XP 三大系统功能差异比较一览图>,现在,再发一张对比图片,简要的看看Windows7家庭普通版.家庭高级版.专业版.旗舰版这四个版 ...
- windows身份验证模式和SQL server身份验证模式 有什么不同
两个验证方式是有明显不同的. 主要集中在信任连接和非信任连接. windows 身份验证相对于混合模式更加安全,使用本连接模式时候,sql不判断sa密码,而仅根据用户的windows权限来进行身份验证 ...
- Hibernate: Truly Understanding the Second-Level and Query Caches--reference
I've written multiple articles here at Javalobby on the Hibernate O/R mapping tool, and they are usu ...
- 动态修改 C 语言函数的实现
Objective-C 作为基于 Runtime 的语言,它有非常强大的动态特性,可以在运行期间自省.进行方法调剂.为类增加属性.修改消息转发链路,在代码运行期间通过 Runtime 几乎可以修改 O ...
- 想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研
想做一个整合开源安全代码扫描工具的代码安全分析平台 - Android方向调研 http://blog.csdn.net/testing_is_believing/article/details/22 ...
- 网站压力测试工具webbench 安装与使用
webbench最多可以模拟3万个并发连接去测试网站的负载能力,个人感觉要比Apache自带的ab压力测试工具好用,安装使用也特别方便,并且非常小. 主要是 -t 参数用着比较爽,下面参考了张宴的文章 ...