Proxy 實現動態代理
阿新 • • 發佈:2021-08-20
檔案結構:
- Child.class [Interface]
- ChildImpl.class
- MyProxy.class [Test Class]
一、Child.class
package proxys;
public interface Child {
void eat();
}
二、ChildImpl.class
package proxys; public class ChildImpl implements Child { @Override public void eat() { System.out.println("Child eating..."); } }
三、MyProxy.class
package proxys; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; import java.lang.reflect.Proxy; /** * 基於介面的動態代理: Proxy, InvocationHandler */ public class MyProxy { /** * Test Method * @param args 引數列表 */ public static void main(String[] args) { // 未使用代理模式 ChildImpl child = new ChildImpl(); child.eat(); // 使用動態代理增強日誌功能 System.out.println(); Child proxyObj = getProxyObj(child, Child.class); proxyObj.eat(); } /** * 獲取代理物件 * @param obj 被代理的物件 * @param interfaceType 被代理方法所屬的介面型別 * @return 代理物件 */ public static <I> I getProxyObj(Object obj, Class<I> interfaceType) { // 介面型別檢查, 因為 Proxy 是基於介面的動態代理 Class<?>[] type = null; Class<?>[] interfaces = obj.getClass().getInterfaces(); for (Class<?> anInterface : interfaces) { if (anInterface.equals(interfaceType)) { type = new Class[]{anInterface}; break; } } if (null == type) { throw new ClassCastException("無法將物件 " + obj + " 代理為 " + interfaceType.getName()); } Object o = Proxy.newProxyInstance(obj.getClass().getClassLoader(), type, new InvocationHandler() { @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { // 增強呼叫前的功能 System.out.println("[" + method.getName() + "] Proxy begin..."); // 呼叫被代理物件的方法 Object ret = method.invoke(obj, args); // 增強呼叫後的功能 System.out.println("[" + method.getName() + "] Proxy end..."); return ret; } }); return (I) o; } }
執行結果:
Child eating...
[eat] Proxy begin...
Child eating...
[eat] Proxy end...