Java動態代理一個淺顯易懂的例子
阿新 • • 發佈:2018-12-17
簡單用途,在不修改一個類的前提下,在該類的方法執行前或執行後加入一些特殊的處理,如日誌、事務等。
要點:
1、需要使用介面類
2、使用動態代理在方法呼叫時加入自己的處理
示例程式碼:
1、介面類
package proxy;
public interface Subject {
public void rent();
public void hello(String str);
}
2、實現類
package proxy; public class RealSubject implements Subject { @Override public void rent() { System.out.println("I want to rent my house"); } @Override public void hello(String str) { System.out.println("hello: " + str); } }
3、動態代理類
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Method; public class DynamicProxy implements InvocationHandler { // 這個就是我們要代理的真實物件 private Object subject; // 構造方法,給我們要代理的真實物件賦初值 public DynamicProxy(Object subject) { this.subject = subject; } @Override public Object invoke(Object object, Method method, Object[] args) throws Throwable { System.out.println("\r\nMethod:" + method); // 在代理真實物件前我們可以新增一些自己的操作 System.out.println("before invoke method " + method.getName()); // 當代理物件呼叫真實物件的方法時,其會自動的跳轉到代理物件關聯的handler物件的invoke方法來進行呼叫 method.invoke(subject, args); // 在代理真實物件後我們也可以新增一些自己的操作 System.out.println("after invoke method " + method.getName()); return null; } }
4、應用類
package proxy; import java.lang.reflect.InvocationHandler; import java.lang.reflect.Proxy; public class Client { public static void main(String[] args) { // 我們要代理的真實物件 Subject realSubject = new RealSubject(); // 我們要代理哪個真實物件,就將該物件傳進去,最後是通過該真實物件來呼叫其方法的 InvocationHandler handler = new DynamicProxy(realSubject); /* * 通過Proxy的newProxyInstance方法來建立我們的代理物件,我們來看看其三個引數 第一個引數 * handler.getClass().getClassLoader() * ,我們這裡使用handler這個類的ClassLoader物件來載入我們的代理物件 * 第二個引數realSubject.getClass().getInterfaces(),我們這裡為代理物件提供的介面是真實物件所實行的介面 * ,表示我要代理的是該真實物件,這樣我就能呼叫這組介面中的方法了 第三個引數handler, 我們這裡將這個代理物件關聯到了上方的 * InvocationHandler 這個物件上 */ Subject subject = (Subject) Proxy.newProxyInstance(handler.getClass().getClassLoader(), realSubject.getClass().getInterfaces(), handler); System.out.println(subject.getClass().getName()); subject.rent(); subject.hello("world"); } }
輸出結果:
com.sun.proxy.$Proxy0
Method:public abstract void proxy.Subject.rent()
before invoke method rent
I want to rent my house
after invoke method rent
Method:public abstract void proxy.Subject.hello(java.lang.String)
before invoke method hello
hello: world
after invoke method hello
參考: