jdk动态代理实现原理
来源:互联网 发布:希拉里女儿 知乎 编辑:程序博客网 时间:2024/05/22 17:10
写在前面:
大神和diao炸天的亲请绕道..
关于代理模式的概念这里省去,大家可以放鸟尽情搜..
关于为什么叫动态代理,个人理解是代理的类是在运行时动态生成的,大家也可以参考网上的理解..
文笔很差,所以文字较少,都在代码和注释中..
=======一点不华丽的分割线-------------------------
开门见山,lets Go..
Java中可以通过jdk提供的 Proxy.newProxyInstance静态方法来创建动态代理对象,下面先来看看这个方法的实现
- public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h)
- throws IllegalArgumentException {
-
-
- if (h == null) {
- throw new NullPointerException();
- }
-
-
-
-
- Class cl = getProxyClass(loader, interfaces);
-
-
-
- try {
- Constructor cons = cl.getConstructor(constructorParams);
- return (Object) cons.newInstance(new Object[] { h });
- } catch (NoSuchMethodException e) {
- throw new InternalError(e.toString());
- } catch (IllegalAccessException e) {
- throw new InternalError(e.toString());
- } catch (InstantiationException e) {
- throw new InternalError(e.toString());
- } catch (InvocationTargetException e) {
- throw new InternalError(e.toString());
- }
- }
下面通过个例子来说明下:先来定义一个接口,jdk的动态代理基于接口来创建代理类,不能基于类的原因是java不支持多重继承,而代理类都会继承Proxy类(个人理解).
-
-
-
-
-
-
- public interface Subject {
- void pub(String key, String content);
-
- String sub(String key);
- }
再来一个具体的实现,在代理模式中可以叫它的实例可以叫target,这个是真正执行操作的对象-
-
-
-
-
-
- public class SimpleSubject implements Subject {
- private Map<String, String> msg = new ConcurrentHashMap<String, String>();
-
- public void pub(String key, String content) {
- System.out.println("pub msg: key is " + key + ", content is " + content);
- msg.put(key, content);
- }
-
- public String sub(String key) {
- if (msg.containsKey(key)) {
- String ret = msg.get(key);
- System.out.println("sub msg: key is " + key + ", result is " + ret);
- return ret;
- }
-
- return null;
- }
-
- }
好,接下来我们来写个动态代理工厂,根据 不同的target来创建动态代理对象-
-
-
-
-
-
- public class SubjectProxyFactory {
-
- public static Subject getSubject(final Subject realSubject) {
- return (Subject) Proxy.newProxyInstance(realSubject.getClass().getClassLoader(), new Class[] { Subject.class },
- new InvocationHandler() {
-
- public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
- System.out.println("\naction before method invocation....");
- Object retVal = method.invoke(realSubject, args);
- System.out.println("action after method invocation....\n");
- return retVal;
- }
- });
- }
- }
可以看到这是一个简单的实现,只是在真实对象执行前后各打一句信息..
接下来用一个 main函数来把这些结合起来 -
-
-
-
-
-
- public class Demo {
- public static void main(String[] args) {
-
- System.setProperty("sun.misc.ProxyGenerator.saveGeneratedFiles", "true");
-
-
- Subject subj = new SimpleSubject();
- subj.pub("name", "kevin.fan");
- subj.sub("name");
-
-
- Subject proxy = SubjectProxyFactory.getSubject(subj);
- proxy.pub("hobby", "r&b music");
- proxy.sub("name");
- }
- }
ok,小手抖一下,走你,看下执行结果- pub msg: key is name, content is kevin.fan
- sub msg: key is name, result is kevin.fan
-
-
- action before method invocation....
- pub msg: key is hobby, content is r&b music
- action after method invocation....
-
-
-
-
- action before method invocation....
- sub msg: key is name, result is kevin.fan
- action after method invocation....
可以看到在调用代理对象的方法时,添加的额外动作已经生效,接下来我们看下生成的代理类的代码..
- import com.aliyun.demo.kevin.coder.lang.proxy.Subject;
- import java.lang.reflect.InvocationHandler;
- import java.lang.reflect.Method;
- import java.lang.reflect.Proxy;
- import java.lang.reflect.UndeclaredThrowableException;
-
-
- public final class $Proxy0 extends Proxy
- implements Subject
- {
-
-
- private static Method m4;
- private static Method m1;
- private static Method m3;
- private static Method m0;
- private static Method m2;
-
- static
- {
- try
- {
- m4 = Class.forName("com.aliyun.demo.kevin.coder.lang.proxy.Subject").getMethod("sub", new Class[] { Class.forName("java.lang.String") });
- m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
- m3 = Class.forName("com.aliyun.demo.kevin.coder.lang.proxy.Subject").getMethod("pub", new Class[] { Class.forName("java.lang.String"), Class.forName("java.lang.String") });
- m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]);
- m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
- return;
- }
- catch (NoSuchMethodException localNoSuchMethodException)
- {
- throw new NoSuchMethodError(localNoSuchMethodException.getMessage());
- }
- catch (ClassNotFoundException localClassNotFoundException)
- {
- throw new NoClassDefFoundError(localClassNotFoundException.getMessage());
- }
- }
-
-
-
- public $Proxy0 paramInvocationHandler)
- throws
- {
- super(paramInvocationHandler);
- }
-
-
- public final String sub(String paramString)
- throws
- {
- try
- {
-
- return (String)this.h.invoke(this, m4, new Object[] { paramString });
- }
- catch (Error|RuntimeException localError)
- {
- throw localError;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
-
- public final boolean equals(Object paramObject)
- throws
- {
- try
- {
- return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue();
- }
- catch (Error|RuntimeException localError)
- {
- throw localError;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
-
- public final void pub(String paramString1, String paramString2)
- throws
- {
- try
- {
- this.h.invoke(this, m3, new Object[] { paramString1, paramString2 });
- return;
- }
- catch (Error|RuntimeException localError)
- {
- throw localError;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
-
- public final int hashCode()
- throws
- {
- try
- {
- return ((Integer)this.h.invoke(this, m0, null)).intValue();
- }
- catch (Error|RuntimeException localError)
- {
- throw localError;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
-
- public final String toString()
- throws
- {
- try
- {
- return (String)this.h.invoke(this, m2, null);
- }
- catch (Error|RuntimeException localError)
- {
- throw localError;
- }
- catch (Throwable localThrowable)
- {
- throw new UndeclaredThrowableException(localThrowable);
- }
- }
-
- }
-------------END
by Kevin Fan
from: http://blog.csdn.net/moreevan/article/details/11642445
0 0