动态代理样例:
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());
}
}