為什麼要使用代理。
假如我們是團隊開發,那麼本團隊的某個類可能並不願意暴露給其他的調用者.這時候又需要用到這個類的一些功能,那麼最好的方式就是以代理的方式提供給調用者.對於一個掉用者來說,它僅僅需要的是知道提供給它的類能執行某個商務邏輯就行了.它完全沒必要清楚的瞭解真正的實施者是誰.
另外對於切面性問題也可以使用代理,
例如:在使用者管理類,有添加、刪除兩個個方法,已經定義好了,但是來了新需求,要在每個方法執行之前加一些驗證資訊,這樣,對於每一個方法都要進行修改,這時候就違背了開閉原則。
程式碼範例如下:
介面:
public interface UserManager {
public void addUser(String userName, String password);
public void delUser(String userId);
}
沒有代理的實作類別:
public class UserManagerImp implements UserManager {
public void addUser(String userName, String password) {
//添加方法之前加入驗證方法
checkSecurity();
System.out.println("--------UserManager.addUser()------");
}
public void delUser(String userId) {
//刪除方法之前加入驗證方法
checkSecurity();
System.out.println("--------UserManager.delUser()------");
}
//需要加入的驗證方法。
public void checkSecurity() {
System.out.println("-----checkSecurity----");
}
}
加入靜態代理的實作類別:
public class UserManagerImplProxy implements UserManager {
private UserManager userManager;
//建構函式,DI注入方式
public UserManagerImplProxy(UserManager userManager) {
this.userManager = userManager;
}
public void addUser(String username, String password) {
checkSecurity();//加入驗證
userManager.addUser(username, password); //執行方法
}
public void delUser(int userId) {
checkSecurity();//加入驗證
userManager.delUser(userId);
}
//需要加入的驗證方法。
private void checkSecurity() {
System.out.println("-------checkSecurity-------");
}
}
但是靜態代理並沒有解決真正的問題,也就是說靜態代理類還是違背了開閉原則。於是動態代理就出現了:
介面
public interface UserManager {
public void addUser(String userName, String password);
public void delUser(String userId);
}
實作類別:
public class UserManagerImp implements UserManager {
public void addUser(String userName, String password) {
System.out.println("--------UserManager.addUser()------");
}
public void delUser(String userId) {
System.out.println("--------UserManager.delUser()------");
}
}
動態代理實作類別
public class SecurityHandler implements InvocationHandler {
private Object targetObject;
//組建代理程式執行個體
public Object createProxyInstance(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 {
//執行方法前進行驗證
checkSecurity();
//執行目標類的方法
Object rest = method.invoke(targetObject, args);
return rest;
}
//需要加入的驗證的方法
public void checkSecurity() {
System.out.println("-----checkSecurity----");
}
}
用戶端:
public class Client {
public static void main(String[] args) {
//執行個體化代理類
SecurityHandler handler = new SecurityHandler();
//通過代理類來執行個體化userManager
UserManager userManager = (UserManager)handler.createProxyInstance(new UserManagerImp());
//執行添加方法,實際上是在代理類的invoke方法中執行。
userManager.addUser("zhang san ", "123");
}
}