动态代理样例:
IGamePlayer gamePlayer = new GamePlayer("张三"); InvocationHandler handler=new GamePlayIH(gamePlayer); ClassLoader cl=gamePlayer.getClass().getClassLoader(); //该方法必须有classLoader、getInterfaces、InvocationHandler IGamePlayer proxy=(IGamePlayer) Proxy.newProxyInstance(cl, gamePlayer.getClass().getInterfaces(), handler); proxy.login("yinyueml", "sssss"); proxy.killBoss(); proxy.upgrade(); //具体实现InvocationHandler public class GamePlayIH implements InvocationHandler { Class cls = null; Object obj = null; public GamePlayIH(Object obj) { this.obj = obj; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { //先调用类的方法 Object result=method.invoke(this.obj, args); //根据运行的方法做出操作。 if(method.getName().equalsIgnoreCase("login")){ System.out.println("有人再用我的账号登陆"); } return result; } }
运行结果为:
登陆用户名:yinyueml;玩家:张三上线 有人再用我的账号登陆
如果
//根据运行的方法做出操作。 if(method.getName().equalsIgnoreCase("login")){ System.out.println("有人再用我的账号登陆"); } Object result=method.invoke(this.obj, args);
运行结果为:
有人再用我的账号登陆 登陆用户名:yinyueml;玩家:张三上线
方法 newProxyInstance
@CallerSensitive //详细分析这个注解 public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException { //判断h是否为空 Objects.requireNonNull(h); 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. */ //该方法会返回一个动态代理类$Proxy0。即如果原先有相同的代理类,则直接用原来的,如果没有则新生成。需要提取,代码如下 Class<?> cl = getProxyClass0(loader, intfs); /* * Invoke its constructor with the designated invocation handler. */ try { if (sm != null) { checkNewProxyPermission(Reflection.getCallerClass(), cl); } final Constructor<?> cons = cl.getConstructor(constructorParams); final InvocationHandler ih = h; if (!Modifier.isPublic(cl.getModifiers())) { AccessController.doPrivileged(new PrivilegedAction<Void>() { public Void run() { cons.setAccessible(true); return null; } }); } //加载器初始化h return cons.newInstance(new Object[]{h}); } catch (IllegalAccessException|InstantiationException e) { throw new InternalError(e.toString(), e); } catch (InvocationTargetException e) { Throwable t = e.getCause(); if (t instanceof RuntimeException) { throw (RuntimeException) t; } else { throw new InternalError(t.toString(), t); } } catch (NoSuchMethodException e) { throw new InternalError(e.toString(), e); } }
$Proxy0源代码
package com.sun.proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; import java.lang.reflect.UndeclaredThrowableException; import proxyPattern.IGamePlayer; //$Proxy()继承Proxy,将InvocationHandler通过构造方法的方式调用,并且在方法中进行调用invoke public final class $Proxy0 extends Proxy implements IGamePlayer { private static Method m1; private static Method m2; private static Method m5; private static Method m4; private static Method m3; private static Method m0; public $Proxy0(InvocationHandler paramInvocationHandler) throws { super(paramInvocationHandler); } public final boolean equals(Object paramObject) throws { try { return ((Boolean)this.h.invoke(this, m1, new Object[] { paramObject })).booleanValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { } throw new UndeclaredThrowableException(localThrowable); } public final String toString() throws { try { return (String)this.h.invoke(this, m2, null); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { } throw new UndeclaredThrowableException(localThrowable); } //该处upgrade调用invoke public final void upgrade() throws { try { this.h.invoke(this, m5, null); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { } throw new UndeclaredThrowableException(localThrowable); } //该处killBoss调用invoke public final void killBoss() throws { try { this.h.invoke(this, m4, null); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { } throw new UndeclaredThrowableException(localThrowable); } //该处login调用invoke public final void login(String paramString1, String paramString2) throws { try { //此处m3代表的为login方法,getName为login this.h.invoke(this, m3, new Object[] { paramString1, paramString2 }); return; } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { } throw new UndeclaredThrowableException(localThrowable); } public final int hashCode() throws { try { return ((Integer)this.h.invoke(this, m0, null)).intValue(); } catch (RuntimeException localRuntimeException) { throw localRuntimeException; } catch (Throwable localThrowable) { } throw new UndeclaredThrowableException(localThrowable); } static { try { m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") }); m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]); m5 = Class.forName("proxyPattern.IGamePlayer").getMethod("upgrade", new Class[0]); m4 = Class.forName("proxyPattern.IGamePlayer").getMethod("killBoss", new Class[0]); m3 = Class.forName("proxyPattern.IGamePlayer").getMethod("login", new Class[] { Class.forName("java.lang.String"), Class.forName("java.lang.String") }); m0 = Class.forName("java.lang.Object").getMethod("hashCode", new Class[0]); return; } catch (NoSuchMethodException localNoSuchMethodException) { throw new NoSuchMethodError(localNoSuchMethodException.getMessage()); } catch (ClassNotFoundException localClassNotFoundException) { } throw new NoClassDefFoundError(localClassNotFoundException.getMessage()); } }