JAVA 中的動態代理
動態代理和靜態代理類的區別在於,動態代理可以在程序運行時,動態地創建代理類,執行被代理類方法的同時,可以運行被代理類調用的拓展方法
JDK 實現的動態代理
JDK 的動態代理要通過import java.lang.reflect
包中的內容實現,代理類需要調用該包下的Proxy
類下的newProxyInstance
方法,返回一個Object
類型的對象,這個對象就是實現代理類功能的對象,通過強制轉換,可以轉換爲被代理類的對象使用
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
上邊是newProxyInstance
方法的定義,該方法中有三個參數,第一個ClassLoader
類型是一個類加載器,這個參數是要加載當前的代理類,即假如代理類名爲userServiceProxy
,這裏的參數即爲userServiceProxy.class.getClassLoader()
,第二個則是一個接口,用來表示包含被代理類全部內容的接口
最後一個參數是一個InvocationHandler
的接口,它內部只有一個invoke
方法,用來實現代理類中向被代理類拓展內容的功能,InvocationHandler
類定義如下
public interface InvocationHandler {
public Object invoke(Object proxy, Method method, Object[] args)
throws Throwable;
}
所以我們實現的InvocationHandler
接口也需要重寫這個方法,這個方法也是我們關聯代理類和被代理類的關鍵,該方法需要返回一個Object
類型的對象,我們通過反射,讓被代理類和代理類產生關聯,並且在這方法中,我們可以自行在其中定義拓展內容
代碼
接口、實現類(被代理類)、切面方法類同之前靜態代理的沒有區別,地址戳:靜態代理
代理類
package jdkProxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
/**
* 代理類
*/
public class UserServiceProxy {
public static UserService createUserService() {
UserService userService = new UserServiceImpl();
MyAspcet aspcet = new MyAspcet();
UserService userServiceProxy = (UserService) Proxy.newProxyInstance(
UserServiceProxy.class.getClassLoader(),
userService.getClass().getInterfaces(),
new InvocationHandler(){
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
// TODO Auto-generated method stub
aspcet.before();
Object retObj = method.invoke(userService, args);
System.out.println("攔截到的返回值" + retObj);
aspcet.after();
return retObj;
}
});
return userServiceProxy;
}
}
測試類
package jdkProxy;
/**
* 測試類
*/
public class test {
public static void main(String[] args) {
UserService userService = UserServiceProxy.createUserService();
userService.add();
userService.delete();
}
}
結果
before method
service add
攔截到的返回值null
after method
before method
service delete
攔截到的返回值null
after method