静态代理类:
由程序员创建或由特定工具自动生成源代码,再对其编译。在程序运行前,代理类的.class文件就已经存在了
动态代理类:
与静态代理类对照的是动态代理类,动态代理类的字节码在程序运行时由Java反射机制动态生成,无需程序员手工编写它的源代码。动态代理类不仅简化了编程工作,而且提高了软件系统的可扩展性,因为Java 反射机制可以生成任意类型的动态代理类。java.lang.reflect 包中的Proxy类和InvocationHandler 接口提供了生成动态代理类的能力。
话不多说看代码。。。
package proxyBase; import java.io.IOException; import java.lang.reflect.Constructor; import java.lang.reflect.InvocationHandler; import java.lang.reflect.InvocationTargetException; import java.net.MalformedURLException; import java.util.Arrays; import javax.tools.JavaCompiler; import javax.tools.JavaCompiler.CompilationTask; import javax.tools.StandardJavaFileManager; import javax.tools.ToolProvider; public class MyProxy { static Class<?>[] parameterTypes = { InvocationHandler.class }; protected InvocationHandler h; protected MyProxy(InvocationHandler h) { this.h = h; } public static Object newInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) { // :产生一个代理类的字节码对象 Class<?> c1 = null; try { // :通过getClass0方法可以得到一个代理类的字节码对象 c1 = getClass0(loader, interfaces); } catch (MalformedURLException e1) { e1.printStackTrace(); } Constructor<?> constructor = null; try { /** * 调用子类$Proxy0(InvocationHandler h)构造函数,由于继承了MyProxy类, * 所以又会继续调用父类的MyProxy(InvocationHandler h)构造函数给 h初始化一个值; */ constructor = c1.getDeclaredConstructor(InvocationHandler.class); /** * 返回一个生成的代理类对象,并将InvocationHandler 的实现类对象传入进去。从而达到给h赋值的目的 * */ return constructor.newInstance(h); } catch (NoSuchMethodException | SecurityException | InstantiationException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) { e.printStackTrace(); } return null; } // :用来生成一个代理类对象 private static Class<?> getClass0(ClassLoader loader, Class<?>[] interfaces) throws MalformedURLException { Class<?> forName = null; try { GennerateClass.generate(interfaces[0]); // :动态编译 JavaCompiler compiler = ToolProvider.getSystemJavaCompiler(); StandardJavaFileManager fileMgr = compiler.getStandardFileManager(null, null, null); Iterable units = fileMgr.getJavaFileObjects(System.getProperty("user.dir") + "/src/" + interfaces[0].getPackage().getName() + "/" + interfaces[0].getSimpleName() + "$proxy0.java"); // :"-d", System.getProperty("user.dir")+"/bin/" 用来指定java文件编译后存放的地方 Iterable<String> options = Arrays.asList("-d", System.getProperty("user.dir") + "/bin/"); CompilationTask t = compiler.getTask(null, fileMgr, null, options, null, units); t.call(); try { fileMgr.close(); } catch (IOException e) { e.printStackTrace(); } // :得到代码自动生成代理类的实例对象 forName = Class.forName(interfaces[0].getName() + "$proxy0"); } catch (ClassNotFoundException e) { e.printStackTrace(); } return forName; } }
这个GennerateClass类是用来生成代理类的Java文件的,是通过字符串拼接而成,仅供参考.
1 package proxyBase; 2 3 import java.io.BufferedWriter; 4 import java.io.File; 5 import java.io.FileWriter; 6 import java.io.IOException; 7 import java.lang.reflect.Method; 8 9 public class G