通過以下幾種方式介紹動態代理
- 動態代理涉及到的類
- 動態代理用法
- Proxy類解析
- 動態代理類解析
動態代理涉及到的類
InvocationHandler(Interface)// 處理類
//參數-> 代理類對象,被代理類的方法,被代理類方法參數(MyInvocationHandler 類中有印證)
//返回值-> 被代理類方法返回結果
public Object invoke(Object proxy, Method method, Object[] args)
Proxy(Class)// 動態創建一個代理對象的類
// 參數->類加載器,被代理類實現的接口,InvocationHandler 實現類
// 返回值->代理類(動態生成)
public static Object newProxyInstance(ClassLoader loader,Class<?>[] interfaces,InvocationHandler h)
// 參數->類加載器,被代理類實現的接口
// 返回值->未被實例化的代理類(構造器參數類型為InvocationHandler)
public static Class<?> getProxyClass(ClassLoader loader,Class<?>... interfaces)
動態代理用法
public class Test {
public static void main(String[] args) throws Exception{
proxyTest1();// 方法一
proxyTest2();// 方法二
}
// 動態代理方法一
private static void proxyTest1() {
// 創建訂單方法
OrderInterface order = new OrderService();
InvocationHandler invocationHandler = getInvocationHandler(order);
/**
* Proxy.newProxyInstance 方法三個參數
* ClassLoader loader 類加載器
* Class<?>[] interfaces 訂單類接口
* InvocationHandler h 處理器(內含增強方法-打印處理訂單日志)
*
* 通過類加載器和訂單類接口動態創建代理類,
* 然后將處理器設置進動態代理類,
* 返回實現訂單類接口的動態代理實現類(動態生成)
*
* */
OrderInterface orderInterface = (OrderInterface)Proxy.newProxyInstance(order.getClass().getClassLoader(), order.getClass().getInterfaces(), invocationHandler);
orderInterface.createOrder(new OrderInfo());
}
// 動態代理方法二
private static void proxyTest2() throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
// 創建訂單方法
OrderInterface order = new OrderService();
InvocationHandler invocationHandler = getInvocationHandler(order);
/**
* ClassLoader loader 類加載器
* Class<?>... interfaces 訂單類接口
*
* 通過類加載器和訂單類接口動態創建代理類
* */
Class<?> clazz = Proxy.getProxyClass(order.getClass().getClassLoader(), order.getClass().getInterfaces());
/**
* 獲取參數為InvocationHandler類型的構造器
* */
Constructor constructor = clazz.getConstructor(InvocationHandler.class);
/**
* 將處理器傳進參數里,實例化類,進行調用以達到增強方法的目的
* */
OrderInterface orderInterface = (OrderInterface)constructor.newInstance(invocationHandler);
orderInterface.createOrder(new OrderInfo());
}
// InvocationHandler 處理器
private static InvocationHandler getInvocationHandler(OrderInterface order) {
// 內部實現InvocationHandler接口,增強被代理類方法功能
InvocationHandler invocationHandler = new MyInvocationHandler(order);
return invocationHandler;
}
}
處理類
public class MyInvocationHandler implements InvocationHandler {
private Object object;
public MyInvocationHandler(Object object) {
this.object = object;
}
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println(new StringBuilder("Object proxy-->className:").append(proxy.getClass().getName()));
System.out.println(new StringBuilder("Method method-->methodName:").append(method.getName()));
if (null != args && args.length > 0) {
System.out.println(new StringBuilder("Object[] args-->paramValue:").append(args[0].toString()));
}
System.out.println(new StringBuilder("增強方法:").append("記錄日志...").toString());
Object returnObject = method.invoke(object, args);
return returnObject;
}
}
訂單類接口
public interface OrderInterface {
public void createOrder(OrderInfo order);
}
訂單處理類(執行下單流程)
public class OrderService implements OrderInterface {
public void createOrder(OrderInfo order) {
System.out.print("創建訂單");
try {
for (int i = 0; i < 3; i++) {
Thread.sleep(500);
System.out.print(".");
}
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("");
System.out.println("訂單創建成功");
}
}
實體類
public class OrderInfo {
@Override
public String toString() {
return "ClassName-->OrderInfo";
}
}
Proxy類解析
屬性及構造器
// 構造器參數類型
private static final Class<?>[] constructorParams = { InvocationHandler.class };
// 代理類緩存,采用弱引用方式進行緩存,方便jvm進行gc垃圾回收
private static final WeakCache<ClassLoader, Class<?>[], Class<?>> proxyClassCache = new WeakCache<>(new KeyFactory(), new ProxyClassFactory());
// 處理類,通過構造器進行賦值。1:子類繼承Proxy類,構造器賦值,2:Proxy.newProxyInstance()調用該方法生成代理類,利用反射創建代理類進行構造器賦值
protected InvocationHandler h;
// 提供的兩種構造器限制了我們使用Proxy類只能直接調用靜態方法
private Proxy() {
}
// 創建動態代理類會使用到該構造器
protected Proxy(InvocationHandler h) {
this.h = h;
}
方法
// 獲取代理類(在文章開頭有介紹此方法)。
public static Class<?> getProxyClass(ClassLoader loader, Class<?>... interfaces) throws IllegalArgumentException
{
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
// 獲取代理類
return getProxyClass0(loader, intfs);
}
// 獲取代理類,并且生成代理類實例(在文章開頭有介紹此方法)。
public static Object newProxyInstance(ClassLoader loader, Class<?>[] interfaces, InvocationHandler h) throws IllegalArgumentException
{
// 代碼和getProxyClass方法目的一致,獲取動態代理類。
-------------------------------------------------------------------------
Objects.requireNonNull(h);
final Class<?>[] intfs = interfaces.clone();
final SecurityManager sm = System.getSecurityManager();
if (sm != null) {
checkProxyAccess(Reflection.getCallerClass(), loader, intfs);
}
Class<?> cl = getProxyClass0(loader, intfs);
-------------------------------------------------------------------------
try {
if (sm != null) {
checkNewProxyPermission(Reflection.getCallerClass(), cl);
}
// 通過反射獲取參數為InvocationHandler類型的構造器
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;
}
});
}
// 實例化動態代理類,并指定構造器參數
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);
}
}
// 生成動態代理類
private static Class<?> getProxyClass0(ClassLoader loader, Class<?>... interfaces) {
if (interfaces.length > 65535) {
throw new IllegalArgumentException("interface limit exceeded");
}
// 代理類的獲取及創建(使用了弱引用方式)
return proxyClassCache.get(loader, interfaces);
}
動態代理類解析(生成代理類方法在git中)
// ProxyObject 隨意指定的一個類名,該類繼承了Proxy(構造賦值),實現了OrderInterface接口(實現代理方法)
public final class ProxyObject extends Proxy implements
{
private static Method m1;
private static Method m3;
private static Method m2;
private static Method m0;
// 代理類構造,參數為InvocationHandler 類型。上文介紹了,Proxy 類InvocationHandler 賦值第一種方式:子類繼承Proxy類,構造器賦值
public ProxyObject(InvocationHandler paramInvocationHandler)
{
super(paramInvocationHandler);
}
static
{
try
{
// 反射生成方法內所有方法的Method對象
m1 = Class.forName("java.lang.Object").getMethod("equals", new Class[] { Class.forName("java.lang.Object") });
m3 = Class.forName("proxy.OrderInterface").getMethod("createOrder", new Class[] { Class.forName("proxy.OrderInfo") });
m2 = Class.forName("java.lang.Object").getMethod("toString", new Class[0]);
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());
}
}
// 創建訂單方法(代理方法)
public final void createOrder(OrderInfo paramOrderInfo)
{
try
{
// 執行InvocationHandler實現類的invoke方法(方法參數在文章開頭有介紹)。
this.h.invoke(this, m3, new Object[] { paramOrderInfo });
return;
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
public final boolean equals(Object paramObject)
{
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 String toString()
{
try
{
return (String)this.h.invoke(this, m2, null);
}
catch (Error|RuntimeException localError)
{
throw localError;
}
catch (Throwable localThrowable)
{
throw new UndeclaredThrowableException(localThrowable);
}
}
//hashCode() 略
}