您的位置:首页 > 编程语言 > Java开发

动态代理---动态生成java文件并编译成class文件

2012-11-15 10:34 639 查看
刚看到的这个,太生猛了...以前学动态代理还知其然,不知其所以然的...现在算是有点了解了...

主要是动态编译这点比较有趣,

1 定义一个接口,只有一个方法,sell (为什么要定义这个接口,就不多说了..面向接口编程可以说是必须的)

package com.cjb.proxy;

/**

* 类说明

* 表示商店

* @creator

* @email

* @create-time May 20, 2010 9:43:40 AM

*/

public interface Store

{

public void sell();

}

2 定义一个实现类,在这里, 这个类就是被代理类..我们需要为这个类产生一个代理.

package com.cjb.proxy;

/**

* 类说明

* @creator

* @email

* @create-time May 20, 2010 9:54:48 AM

*/

public class Supermarket implements Store

{

@Override

public void sell()

{

System.out.println("sel in supermarket.....");

}

}

3 下面是测试类.我们在这个类里动态的生成了一个代理类Dealer.java ,然后动态的编译这个类,最后调用这个类的方法.

package com.cjb.proxy;

import java.io.File;

import java.io.FileWriter;

import java.lang.reflect.Constructor;

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;

/**

* 类说明

*

* @creator

* @email

* @create-time May 20, 2010 10:11:29 AM

*/

public class Test

{

public static void main(String[] args) throws Exception

{

String rt = "\r\n";

String source = "package com.cjb.proxy;" + "/**" + " * 类说明"+ rt

+ "* @creator " + " * @email "+ rt

+ " * @create-time May 20, 2010 10:05:23 AM " + " */"+ rt

+ "public class Dealer implements Store"+ rt + "{"+ rt + "private Store s;" + rt +

"public Dealer(Store s)"+ rt + " {" + " this.s = s;"+ rt

+ " }" + rt +

" public void sell()" + " {"+ rt

+ " System.out.println(\"price markup....\");"+ rt

+ " s.sell();" + " }" + rt+

"}";

String fileName = System.getProperty("user.dir")//获取到项目的根路径

+ "/src/com/cjb/proxy/Dealer.java";

File f = new File(fileName);

FileWriter fw = new FileWriter(f);

fw.write(source);

fw.flush();

fw.close();//这里只是产生一个JAVA文件,简单的IO操作

// compile下面开始编译这个Store.java

JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();

StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null,

null, null);

Iterable units = fileMgr.getJavaFileObjects(fileName);

CompilationTask t = compiler.getTask(null, fileMgr, null, null, null,

units);

t.call();

fileMgr.close();

// load into memory and create an instance

URL[] urls = new URL[] { new URL("file:/"

+ System.getProperty("user.dir") + "/src") };

URLClassLoader ul = new URLClassLoader(urls);

Class c = ul.loadClass("com.cjb.proxy.Dealer");

System.out.println(c);

//客户端调用

Constructor ctr = c.getConstructor(Store.class);

Store s = (Store)ctr.newInstance(new Supermarket());//这里看到,这个我们这个代理类必须实现Store的原因

s.sell();

}

}

总结下

这节的内容说的是动态的产生java文件并编译它..其实,说起来,我们直接写一个java文件会方便很多,因为其实我们的代码都在字符串source中的,但是,为什么还要这样费事的动态去产生,主要目的就是让项目少一个类.少一个JAVA文件.还有一个目的,可以看到,我们动态产生的这个类,在最后调用的时候,我们是不需要知道他的类名的.重要点在于动态.看懂了这个下面的动态代理才能知道根本
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: