上一篇博客是最基本的动态代理原理的实现,因为其固定了接口,固定了代理方法,以及固定了代理的类型,
接下来的博客系类将一步步渐入深度介绍java的动态代理的实现原理

****************************************************************************
首先补充一下“java代理”的相关知识,静态代理的实现包括两种方式,一是聚合,另一种是继承。
聚合是指通过接口,调用其实现类的具体方法:比如接口i,含有方法run(); 类A 实现了接口i,当然
也实现了方法run(); 类B于是就可以通过new一个接口 i 的对象,调用A的run()方法,并在run()方法前后实现其他操作,
这样就实现了对A的run()方法的代理;
继承当然更好理解,就是把run()方法重写,从而实现代理
但是,一旦代理的操作很多,需要写的类都非常的繁杂,就需要不断的写代理类,不断的更新代理操作,于是这就有了动
态代理。

*****************************************************************************

这次要对实现任意接口的类进行代理。

1、接口

public interface Moveable {
void move();
}

  

2、被代理的对象

 public class Tank implements Moveable {

     @Override
public void move() { System.out.println("Tank Moving...");
try {
Thread.sleep(new Random().nextInt(10000));
} catch (InterruptedException e) {
e.printStackTrace();
} } }

3、用于产生代理对象

 public class Proxy {
//产生新的动态代理类
public static Object newProxyInstance(Class intf) throws Exception{ //将接口当成参数传入,这样就可以代理实现了任意接口的类,而不仅是实现了Moveable接口
//将一下字符串动态编译,生成代理类
//实现方式有以下击中:jdk6.0 complier API;CGLib; ASM
String rt = "\r\n";
String src =
"public class TankTimeProxy implements " +intf.getName()+ "{"+rt+ //直接用intf,是调用toString方法,前会加入字符串 interface
intf.getName()+" t;"+rt+ " public TankTimeProxy("+intf.getName()+" t) {"+rt+
" this.t = t;"+rt+
" }"+rt+ " @Override"+rt+
" public void move() {"+rt+
" long start = System.currentTimeMillis();"+rt+
" System.out.println(\"start time is \"+start);"+rt+
" t.move();"+rt+
" long end = System.currentTimeMillis();"+rt+
" System.out.println(\"end time is \"+end);"+rt+
" System.out.println(\"time is \"+(end - start));"+rt+
" }"+rt+
"}"; //进行编译
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)
//管理动态生成的文件
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(); //************以上过程获得了java文件源码,编译生成了java文件的class文件*******
//加载至内存,生成新对象
//Class.load(0 是加载path路径的class文件
//URLClassLoader是将硬盘中的class文件加载进入 //通过Url引入本地文件
URL[] urls = new URL[]{new URL("file:/"+"g:/src/")}; //指定生成class文件的位置,与java文件放置在同一目录
//去指定路径寻找class文件
URLClassLoader urlClassLoader = new URLClassLoader(urls); Class c = urlClassLoader.loadClass("TankTimeProxy"); System.out.println(c); //执行
//c.newInstance(); 是调用空的构造方法 //获得构造方法
//根据java虚拟机,每一个构造方法也相当于一个对象
Constructor constructor = c.getConstructor(intf); //产生新对象
Moveable m = (Moveable) constructor.newInstance(new Tank()); //new Tank()为构造方法的参数 即被代理对象 m.move(); return m;
}
}

4、测试端

 public class Client {
public static void main(String[] args) throws Exception { //这里任然以Moveable接口为例传入,因为在Proxy中为节省麻烦,还是固定生成了Moveable,后来会慢慢简化的,其实是可以传递任意的的接口的
Moveable m =(Moveable) Proxy.newProxyInstance(Moveable.class);
m.move(); }
}

5、结果

(1)生成的java与class文件

(2)java文件的代码

(3)运行结果

深度模拟java动态代理实现机制系类之一的更多相关文章

  1. 深度模拟java动态代理实现机制系类之三

    这里的内容就比较复杂了,要实现的是对任意的接口,对任意指定的方法,以及对任意指定的代理类型进行代理,就更真实的模拟出java虚拟机的动态代理机制 罗列一下这里涉及的类.接口之间的关系,方便大家学习.1 ...

  2. 深度模拟java动态代理实现机制系类之二

    这次我们要实现的是对任意接口,任意的方法进行特定的代理 这里不一样的只有Proxy类,要实现对所有方法进行代理,那么重点就在于获得接口的所有方法 import java.io.File; import ...

  3. 透过字节码生成审视Java动态代理运作机制

    对于动态代理我想应该大家都不陌生,就是可以动态去代理实现某个接口的类来干一些我们自己想要的功能,但是在字节码层面它的表现是如何的呢?既然目前刚好在研究字节码相关的东东,有必要对其从字节码角度来审视一下 ...

  4. Java 动态代理机制分析及扩展

    Java 动态代理机制分析及扩展,第 1 部分 王 忠平, 软件工程师, IBM 何 平, 软件工程师, IBM 简介: 本文通过分析 Java 动态代理的机制和特点,解读动态代理类的源代码,并且模拟 ...

  5. [转]Java 动态代理机制分析及扩展

    引言 Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执 ...

  6. Java 动态代理机制分析及扩展--转

    http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/#icomments http://www.ibm.com/developerworks/c ...

  7. Java 动态代理机制分析及扩展,第 1 部分

    Java 动态代理机制分析及扩展,第 1 部分 http://www.ibm.com/developerworks/cn/java/j-lo-proxy1/ 本文通过分析 Java 动态代理的机制和特 ...

  8. JAVA动态代理的全面深层理解

    Java 动态代理机制的出现,使得 Java 开发人员不用手工编写代理类,只要简单地指定一组接口及委托类对象,便能动态地获得代理类.代理类会负责将所有的方法调用分派到委托对象上反射执行,在分派执行的过 ...

  9. 一文读懂Java动态代理

    作者 :潘潘 日期 :2020-11-22 事实上,对于很多Java编程人员来说,可能只需要达到从入门到上手的编程水准,就能很好的完成大部分研发工作.除非自己强主动获取,或者工作倒逼你学习,否则我们好 ...

随机推荐

  1. SVN安装笔记

    1.先去以下网址去下载服务器端与客户端的SVN 2.服务端SVN的安装 点击next 点击next 再点击next 点击next 点击install 点击Finish,这样服务器端的SVN就安装好了, ...

  2. 在Linux下安装C/C++开发工具包的最佳方式

    假设你使用的是Fedora, Red Hat, CentOS, 或者 ScientificLinux 系统,使用以下的命令安装GNU的C/C++开发包和编译器. # yum groupinstall ...

  3. 华为的JAVA面试题及答案(部分)

    华为的JAVA面试题 (后记:没有想到华为的面试题就是非同一般,非常多题不是一眼就行看得出来,至少对我这种鸟来说是这样.对我个人来说,看看这种题,可能比看<Think In Java>都还 ...

  4. materialish-progress

    https://github.com/pnikosis/materialish-progress materialish-progress-master.zip

  5. Microsoft Visual Studio与Firefly 加载的项目已建议,更新源代码地位问题

    一开始装笔记本vs2010,由于使用的近期发展vs2008与vs2005所以,今天再次2008.2005安装在,但是在打开的项目时,,首先提示加载项目文件.然后已建议状态,非常慢非常慢的,之前仅仅有v ...

  6. android学习日记11--音频播放类

    一.android 音频播放类 MediaPlayer和SoundPool都可以用来播放音频.区别是MediaPlayer占用资源高,延迟时间高,播放长音乐的,并且不能同时播放多个音乐,而SoundP ...

  7. flash builder 4.7 debug via usb device iPhone 4s - device not found

    http://forums.adobe.com/message/4865192 Please provide more info on the above issue: 1.What is the m ...

  8. [Effective C++ --022]将成员变量声明为private

    这一章并没有什么太多的内容,作者无非想告诉我们一件事:成员变量应该是private. 为此,他列举了以下的理由: 1.成员函数来返回成员变量是非常高效: 2.protected成员变量并不比publi ...

  9. 学通javaweb 24堂课 学习笔记

    17.01:简单配置控制器 1.一个controller protected ModelAndView handleRequestInternal(HttpServletRequest request ...

  10. sscanf、strsep

    #include <stdio.h> #include <string.h> int main() { char token[] ="abdzxbcdefgh&quo ...