
Object proxy = Proxy.newProxyInstance(ClassLoader loader, Class>[]interfaces, InvocationHandler h)
上面代碼會生成一個代理類對象proxy, 通過代理類就可以訪問到 realSubject的行為(method),具體怎麼訪問的,咱們接著說。
Proxy.class
// InvocationHandler是Proxy的屬性
protected Proxy(InvocationHandler h) {
Objects.requireNonNull(h);
this.h = h;
}
public static Object newProxyInstance(ClassLoader loader,
Class>[] interfaces,
InvocationHandler h)
throws IllegalArgumentException
{
......
/*
* Look up or generate the designated proxy class.
*/
Class> cl = getProxyClass0(loader, intfs);
......
}
/**
* A factory function that generates, defines and returns the proxy class given
* the ClassLoader and array of interfaces.
*/
private static final class ProxyClassFactory
implements BiFunction<classloader>[], Class>>
{
// 代理類的名稱前綴
private static final String proxyClassNamePrefix = "$Proxy";
@Override
public Class> apply(ClassLoader loader, Class>[] interfaces) {
......
/*
* 生成代理類.
*/
byte[] proxyClassFile = ProxyGenerator.generateProxyClass(
proxyName, interfaces, accessFlags);
return defineClass0(loader, proxyName,
proxyClassFile, 0, proxyClassFile.length);
......
}
}
/<classloader>
通過上面的源碼,我們可以看到:
- InvocationHandler是Proxy的屬性;
- 使用ProxyGenerator.generateProxyClass 可以生成代理類對象;
接下來我們通過實例來說明原理:
// 定義一個接口
public interface UserService {
void query();
}
// 接口的實現類
public class UserServiceImpl implements UserService{
@Override
public void query() {
System.out.println("Query user ...");
}
}
// InvocationHandler的實現
public class InvocationHandlerImpl implements InvocationHandler {
private UserService userService;
// 傳入真實的對象
public InvocationHandlerImpl(UserService userService) {
this.userService = userService;
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("before method invoke ...");
method.invoke(userService, null);
System.out.println("after method invoke ...");
return null;
}
}
// 通過代理類調用方法
public class JdkProxy {
public static void main(String[] args) {
UserServiceImpl userService = new UserServiceImpl();
UserService us = (UserService) Proxy.newProxyInstance(userService.getClass().getClassLoader(), userService.getClass().getInterfaces(),
new InvocationHandlerImpl(userService));
us.query();
}
}
上面代碼的執行結果:
before method invoke ...
Query user ...
after method invoke ...
還有個問題,就是上面的Proxy怎麼可以直接轉化為UserService,我們上面也說過,使用ProxyGenerator.generateProxyClass 可以生成代理類對象,那麼不妨我們生成代理類看一下源碼:
byte[] proxyClassFile = ProxyGenerator.generateProxyClass("UserServiceProxy", UserServiceImpl.class.getInterfaces());
把上面的字節保存到某個地方,生成UserServiceProxy.class 文件,然後反編譯這個文件,內容如下:
public final class UserServiceProxy extends Proxy implements UserService {
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
public UserServiceProxy(InvocationHandler var1) throws {
super(var1);
}
public final boolean equals(Object var1) throws {
try {
return (Boolean)super.h.invoke(this, m1, new Object[]{var1});
} catch (RuntimeException | Error var3) {
throw var3;
} catch (Throwable var4) {
throw new UndeclaredThrowableException(var4);
}
}
public final void query() throws {
try {
super.h.invoke(this, m3, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final String toString() throws {
try {
return (String)super.h.invoke(this, m2, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
public final int hashCode() throws {
try {
return (Integer)super.h.invoke(this, m0, (Object[])null);
} catch (RuntimeException | Error var2) {
throw var2;
} catch (Throwable var3) {
throw new UndeclaredThrowableException(var3);
}
}
static {
try {
m1 = Class.forName("java.lang.Object").getMethod("equals", Class.forName("java.lang.Object"));
m3 = Class.forName("com.proxy.sample.service.UserService").getMethod("query");
m2 = Class.forName("java.lang.Object").getMethod("toString");
m0 = Class.forName("java.lang.Object").getMethod("hashCode");
} catch (NoSuchMethodException var2) {
throw new NoSuchMethodError(var2.getMessage());
} catch (ClassNotFoundException var3) {
throw new NoClassDefFoundError(var3.getMessage());
}
}
}
通過上面的代碼,我們可以很明瞭的看到:
- 代理類也實現了UserService接口;
- 代理類的所有方法調用都是通過 InvocationHandler.invoke 方法實現;
至此,JDK動態代理的原理已很清晰:
實際的調用鏈如下:
Proxy -> InvocationHandler -> RealSubject
而且Proxy含有handler屬性, InvocationHandler 含有subject屬性。
閱讀更多 架構即人生 的文章
關鍵字: UserService 代理 動態