動態代理主要是為了處理重復創建模板代碼的場景。
使用示例
public interface MyInterface {String doSomething();
}public class MyInterfaceImpl implements MyInterface{@Overridepublic String doSomething() {return "接口方法dosomething";}
}public class MyInvocationHandler implements InvocationHandler {private final Object target;public MyInvocationHandler(Object target) {this.target = target;}@Overridepublic Object invoke(Object o, Method method, Object[] objects) throws Throwable {System.out.println("Before method: " + method.getName());Object result = method.invoke(target, objects); // 調用實際對象的方法System.out.println("After method: " + method.getName());return result;}
}public class Execute {public String execute(){MyInterface realObject = new MyInterfaceImpl();MyInterface proxyInstance = (MyInterface) Proxy.newProxyInstance(MyInterface.class.getClassLoader(),new Class<?>[] { MyInterface.class },new MyInvocationHandler(realObject));return proxyInstance.doSomething(); // 調用代理對象的方法,實際調用的是}
}
Proxy.newProxyInstance是Java動態代理的核心方法,其三個參數功能如下:
?ClassLoader loader?
負責加載動態生成的代理類字節碼,通常使用目標接口的類加載器(如UserService.class.getClassLoader())23。該參數決定代理類的JVM加載方式1。
?Class<?>[] interfaces?
指定代理類需要實現的接口數組(如new Class[]{A.class, B.class}),代理對象將具備這些接口定義的方法能力35。注意該參數僅定義接口而非具體被代理對象1。
?InvocationHandler handler?
通過實現invoke方法定義代理邏輯,當調用代理對象方法時會觸發此處理器,參數包含代理實例、方法對象及方法參數45。開發者在此實現橫切邏輯(如日志、事務)