JDK6提供了Javacompiler,StandardJavaFileManager,Iterable
实现对.java文件编译的方法。
框架在实现代理的时候可以使用CGLIB直接生成2进制文件,不需要生成.java文件。
//接口
public interface Moveable {
void move();
void stop();
}
//实现Moveable接口
public class Tank implements Moveable{
public void move() {
System.out.println("tank move()...");
}
public void stop() {
System.out.println("tank stop()...");
}
}
import java.lang.reflect.Method;
//除moveable之外再创建一个接口InvocationHandler
public interface InvocationHandler {
void invoke(Object o,Method m);
}
import java.lang.reflect.Method;
//实现InvocationHandler接口,自定义需要添加的内容,创建添加日志的Handler
public class LogHandler implements InvocationHandler{
Object target;
public LogHandler(Object target) {
this.target = target;
}
public void invoke(Object o, Method m) {
System.out.println("logHandler start...");
try {
m.invoke(target);
} catch (Exception e) {
e.printStackTrace();
}
System.out.println("logHandler end...");
}
}
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;
//模拟JDK的代理类Proxy
public class Proxy {
//模拟JDK创建代理类的方法,JDK中还有一个ClassLoader参数,这里传入接口和需要添加的逻辑Handler,结果返回一个代理的对象。
public static Object newProxyInstance(Class inf,InvocationHandler h) throws Exception{
String methodStr = "";
String rt = "\r\n";
Method[] methods = inf.getMethods();
for(Method m : methods){
methodStr += "@Override" + rt +
"public void " + m.getName() + "() {" + rt +
" try {" + rt +
" Method md = " + inf.getName() + ".class.getMethod(\"" + m.getName() + "\");" + rt +
" h.invoke(this, md);" + rt +
" }catch(Exception e) {e.printStackTrace();}" + rt +
"}";
}
//生成代理对象的类
String src =
"package proxy;" + rt +
"import java.lang.reflect.Method;" + rt +
"public class $Proxy1 implements " + inf.getName() + "{" + rt +
" proxy.InvocationHandler h;" + rt +
" public $Proxy1(InvocationHandler h) {" + rt +
" this.h = h;" + rt +
" }" + rt +
methodStr +
"}";
String fileName =
"D:/share/test/proxy/$Proxy1.java";
File f = new File(fileName);
FileWriter fw = new FileWriter(f);
fw.write(src);//生成.java文件
fw.flush();
fw.close();
//对类进行编译
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(null, null, null);
Iterable units = fileManager.getJavaFileObjects(fileName);
compiler.getTask(null, fileManager, null, null, null, units).call();//编译,生成.class文件。
fileManager.close();
URL[] url = new URL[]{new URL("file:/D:/share/test/")};
URLClassLoader loader = new URLClassLoader(url);
Constructor c = loader.loadClass("proxy.$Proxy1").getConstructor(InvocationHandler.class);//构造器有参数
return c.newInstance(h);//加载.class文件,生成对象。
}
}
public class Client {
public static void main(String[] args) throws Exception {
InvocationHandler h = new LogHandler(new Tank());//告诉代理类,我需要添加什么逻辑。
Moveable m = (Moveable) Proxy.newProxyInstance(Moveable.class, h);//返回代理的对象。
m.move();//实际这里是调用添加过逻辑的代理类的方法。
m.stop();
}
}
分享到:
相关推荐
学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-学生竞赛模拟管理系统java代码-学生竞赛模拟系统设计与实现-基于ssm的学生竞赛模拟系统-基于Web的学生竞赛模拟系统设计与实现-学生竞赛...
学生竞赛模拟-学生竞赛模拟系统-学生竞赛模拟系统源码-学生竞赛模拟管理系统-学生竞赛模拟管理系统java代码-学生竞赛模拟系统设计与实现-基于ssm的学生竞赛模拟系统-基于Web的学生竞赛模拟系统设计与实现-学生竞赛...
第5章介绍了并行程序设计中常见的 些设计模式以及 些典型的并行算法和使用方法,其中包括重要的JavaNIO和AIO的介绍。第6章介绍了 Java 8中为并行计算做的新的改进, 包括并行流、 CompletableFuture、 StampedLock...
一个全面使用JDK1.8语法的J2EE示例,附带模拟数据库操作和基于注解的Bean注入管理。供J2EE开发新手学习。无需spring,掌握SpringMvc主要的开发思路。
8.3 面向对象的设计模式 241 实例156 Singleton单例模式 242 实例157 招聘(简单工厂模式) 243 实例158 同学聚会(工厂方法模式) 244 实例159 图书展(抽象工厂模式) 246 实例160 汽车...
3.7.4 动态代理类的设计模式 3.8 小结 第2篇 线程开发 第4章 学生并发接水(线程Thread) 4.1 学生并发接水原理 4.1.1 项目结构框架分析 4.1.2 项目功能业务分析 4.2 不排队形式学生并发接水 4.2.1 水龙头类 4.2.2 ...
实例1 下载、安装并配置JDK 1 实例2 第一个Java程序 3 实例3 在Eclipse中创建第一个Java程序 4 常见问题 javac不是内部或者外部命令 6 常见问题 找不到类文件 6 常见问题 语法错误 7 第2章 Java基础语法 9 ...
模拟退火算法学生信息-学生信息系统-学生信息系统源码-学生信息管理系统-学生信息管理系统java代码-学生信息系统设计与实现-基于springboot的学生信息系统-基于Web的学生信息系统设计与实现-学生信息网站-学生信息...
jdk1.8+tomcat8.5+mysql5.7 数据库表结构在WebContent/db目录下 ## 项目介绍 实现一个web应用,作为智能家居系统的服务端,接收来自客户端的数据,并能够通过web页面实时显示室内传感器的值,可以使用文本,建议使用...
8.3 面向对象的设计模式 241 实例156 Singleton单例模式 242 实例157 招聘(简单工厂模式) 243 实例158 同学聚会(工厂方法模式) 244 实例159 图书展(抽象工厂模式) 246 实例160 汽车适配器(Adapter适配器模式...
8.3 面向对象的设计模式 241 实例156 Singleton单例模式 242 实例157 招聘(简单工厂模式) 243 实例158 同学聚会(工厂方法模式) 244 实例159 图书展(抽象工厂模式) 246 实例160 汽车适配器...
8.3 面向对象的设计模式 241 实例156 Singleton单例模式 242 实例157 招聘(简单工厂模式) 243 实例158 同学聚会(工厂方法模式) 244 实例159 图书展(抽象工厂模式) 246 实例160 汽车适配器(Adapter...
8.3 面向对象的设计模式 241 实例156 Singleton单例模式 242 实例157 招聘(简单工厂模式) 243 实例158 同学聚会(工厂方法模式) 244 实例159 图书展(抽象工厂模式) 246 实例160 汽车适配器(Adapter适配器模式...
软件设计模式 - MVC 数据库 – MySql Workbench 8.0(Spring Data Jpa) 前端:HTML、CSS、Thymeleaf 数据库连接 问题表 排行榜表 未来更新 • 托管到 Web 服务器 • 按问题大小分开排行榜。 • 管理面板 ...