java的動態代理詳解
1.爲什麼要使用動態代理。
有時候我們在訪問一個對象的時候,需要一些業務的處理,比如權限的控制,日誌的記錄,攔截器等等的一些面向切面的業務,這時候我們可以用攔截器實現。而且Struts的攔截器就是動態代理一個很典型的例子。
2.動態代理的使用
首先介紹幾個類和方法
- Proxy類:位於java.lang.reflect.Proxy,這個類就是用於創建代理對象的核心類
- newProxyInstance方法:Proxy類的newProxyInstance方法返回代理對象 newProxyInstance(ClassLoader loader, Class< ?>[] interfaces, InvocationHandler h)
注意:爲一個類創建動態代理,這個類必須實現接口,說白了,動態代理就是根據實現的接口找到類的方法做處理
//說下newProxyInstance方法的三個參數
ClassLoader loader:定義代理類的類加載器
interfaces:定義代理類所實現的接口
InvocationHandler:實現了InvocationHandler接口的類。
下面就用具體的代碼說明動態代理的使用
//這個是添加用戶的接口
package myexercise.proxy;
public interface UserService {
public void addUser(String userName);
public String findUser(String sql);
}
.
//添加用戶的具體類,想要創建動態代理必須實現接口,這裏實現了UserService接口
package myexercise.proxy;
public class UserServiceImpl implements UserService{
@Override
public void addUser(String userName) {
System.out.println("添加的用戶姓名爲--"+userName);
}
@Override
public String findUser(String userName) {
System.out.println("正在查詢用戶--"+userName);
return "查詢用戶成功";
}
}
.
//創建UserServiceImpl的代理類,實現執行添加用戶方法的時候,輸出該方法是否執行成功,類似日誌記錄的功能。
package myexercise.proxy;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
public class DynamicProxy implements InvocationHandler {
public Object targetObject;
public Object myProxyInstance(Object targetObject){
this.targetObject=targetObject;
return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(),
targetObject.getClass().getInterfaces(), this);
}
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
System.out.println("開始添加用戶...");
Object obj=null;
try {
obj=method.invoke(method.getName(), args);
System.out.println("添加用戶成功");
} catch (Exception e) {
e.printStackTrace();
System.out.println("添加用戶失敗");
}
return obj;
}
.
//這個是客戶端類
package myexercise.proxy;
public class Client {
public static void main(String[] args) {
DynamicProxy dp=new DynamicProxy();
UserService userService=(UserService) dp.myProxyInstance(new UserServiceImpl());
userService.addUser("張三");
}
}