JAVA 设计模式 之 动态代理
2017-05-06 09:50
597 查看
JAVA的设计模式-JDK动态代理:实现控制 被代理类的方法执行前,执行后来做你想做的事。
1.自写代理模式示例代码
接口 public interface Subject{ public void doSomeThing(); }
实现类 public class RealObject implements Subject{ @Override public void doSomeThing() { System.out.println("doSomeThing.."); } }
自写代理类 public class SimpleProxy { Object obj = null; public SimpleProxy(Object obj){ this.obj = obj; } public void doSomeThing(){ System.out.println("SimpleProxy doSomeThing start..."); this.obj.doSomeThing(); System.out.println("SimpleProxy doSomeThing end..."); } }
执行 public class TestProxy { public static void main(String[] args) { Subject obj = new RealObject(); SimpleProxy simplePro = new SimpleProxy(obj); simplePro.doSomeThing(); } } 控制台打印结果 SimpleProxy doSomeThing start... doSomeThing.. SimpleProxy doSomeThing end...
** 2:实现 InvocationHandler 接口 (充当SimpleProxy )来实现代理模式 示例代码**
接口 public interface Subject { public void doSomeThing(); }
实现类 public class RealObject implements Subject{ @Override public void doSomeThing() { System.out.println("doSomeThing.."); } }
代理类 public class DynamicProxy implements InvocationHandler { Object obj = null; public DynamicProxy(Object obj){ this.obj = obj; } @Override public java.lang.Object invoke(java.lang.Object proxy, Method method, java.lang.Object[] args) throws Throwable { System.out.println("proxy class:"+proxy.getClass()); System.out.println("proxy name:"+proxy.getClass().getSimpleName()); System.out.println("method:"+method.getName()); return method.invoke(this.obj, args); } }
测试 public class TestProxy { public static void main(String[] args) { Subject sub = (Subject) Proxy.newProxyInstance(Subject.class.getClassLoader(), new Class[]{Subject.class}, new DynamicProxy(new RealObject())); sub.doSomeThing(); } } 控制台输出: proxy class:class com.sun.proxy.$Proxy0 proxy name:$Proxy0 method:doSomeThing doSomeThing..
The last 分析源代码,实现接口InvocationHandler 具体做了什么。
昨天没有找到源码,,,,表示心也很累,,,, 进入Proxy.newProxyInstance() 方法
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { if (h == null) { throw new NullPointerException(); } final Class<?>[] intfs = interfaces.clone(); final SecurityManager sm = System.getSecurityManager(); if (sm != null) { checkProxyAccess(Reflection.getCallerClass(), loader, intfs); } /* * Look up or generate the designated proxy class. */ Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (sm != null && ProxyAccessHelper.needsNewInstanceCheck(cl)) { // create proxy instance with doPrivilege as the proxy class may // implement non-public interfaces that requires a special permission return AccessController.doPrivileged(new PrivilegedAction<Object>() { public Object run() { return newInstance(cons, ih); } }); } else { return newInstance(cons, ih); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString()); } }
主要的是getProxyClass0()方法的调用,一直跟进,直接到代理工厂类ProxyClassFactory的apply() 其中多的是一些判断,无意看到了一个 IdentityHashMap集合。。呵呵 接着往下走,有一个 ProxyGenerator.generateProxyClass(proxyName, interfaces) proxyName是生产的代理对象类,interfaces是被代理的接口,并返回一个byte[]字节数组
public static byte[] generateProxyClass(String paramString, Class[] paramArrayOfClass) { ProxyGenerator localProxyGenerator = new ProxyGenerator(paramString, paramArrayOfClass); final byte[] arrayOfByte = localProxyGenerator.generateClassFile(); if (saveGeneratedFiles) { AccessController.doPrivileged(new PrivilegedAction() { public Void run() { try { FileOutputStream localFileOutputStream = new FileOutputStream(ProxyGenerator.dotToSlash(this.val$name) + ".class"); localFileOutputStream.write(arrayOfByte); localFileOutputStream.close(); return null; } catch (IOException localIOException) { throw new InternalError("I/O exception saving generated file: " + localIOException); } } }); } return arrayOfByte; }
返回的字节数组是实现了接口interfaces,类名称为proxyName的类, JDK根据既定规则直接生成class文件,用native方法加载了这个类,最终产生了一个实现了一个接口的类
private static native Class defineClass0(ClassLoader loader, String name, byte[] b, int off, int len);
_传入的 new DynamicProxy(new RealObject()) _ 回到Proxy.newProxyInstance 的最后一行
return cons.newInstance(new Object[] {h} );
new DynamicProxy(new RealObject()) 可以理解是为生成的proxyName类转入的一个参数。
。。。。。在写这个的时候了解到CGLIB 也可以实现动态代理。只是产生动态代理对象时不用接口类! 写在离职前的几天。
(adsbygoogle = window.adsbygoogle || []).push({});相关文章推荐
- 【java设计模式:动态代理】
- Java设计模式(四)之动态代理模式
- Java基础 - 类的加载,类加载器,反射,动态代理,模板设计模式,JDK5新特性,枚举(类),JDK1.7新特性
- java学习之路---设计模式---动态代理
- 设计模式中的代理模式与Java中的动态代理
- 设计模式_JAVA动态代理设计模式
- Java设计模式--代理模式与JDK动态代理,cglib动态代理
- 设计模式--对代理模式的思考之java动态代理
- Java设计模式Proxy之动态代理
- java设计模式之代理模式 (静态&动态)
- java设计模式--代理及其动态代理--05
- java设计模式--动态代理
- Java设计模式学习06——静态代理与动态代理
- JAVA设计模式之【代理模式】二(jdk动态代理)
- Java设计模式---代理模式(二)---动态代理
- java代理设计模式(静态代理与动态代理)
- [转]转个经典的帖子:说故事学设计模式之-Java动态代理模式
- java 设计模式 代理 静态和动态
- 动态代理(JAVA设计模式)
- java设计模式之静态代理与动态代理