一、概念java
代理模式爲其餘對象提供一個代理以控制對這個對象的訪問,屬於結構性模式。從代碼的角度來分,代理能夠分爲兩種:一種是靜態代理,另外一種是動態代理。 靜態代理就是在程序運行前就已經存在代理類的字節碼文件,代理類和委託類的關係在運行前就肯定了。 動態代理類的源碼是在程序運行期間根據反射等機制動態的生成,因此不存在代理類的字節碼文件。代理類和委託類的關係是在程序運行時肯定。 bash
二、模式結構ide
三、使用場景優化
四、優缺點ui
優勢:this
缺點:spa
五、實例代理
靜態實例code
public interface IUserDao {
int save();
}
複製代碼
public class UserDao implements IUserDao {
@Override
public int save() {
return 0;
}
}
複製代碼
public class UserDaoProxy implements IUserDao {
//接收保存目標對象
private IUserDao target;
public UserDaoProxy(IUserDao target) {
this.target = target;
}
@Override
public int save() {
return target.save();
}
}
複製代碼
動態實例:cdn
仍是使用靜態代理的IUserDao和UserDao 類,改造UserDaoProxy 類,利用java的newProxyInstance動態生成實例。
public class UserDaoProxy {
//維護一個目標對象
private Object target;
public UserDaoProxy(Object target) {
this.target = target;
}
//給目標對象生成代理對象
public Object getProxyInstance() {
return Proxy.newProxyInstance(
target.getClass().getClassLoader(),
target.getClass().getInterfaces(),
new InvocationHandler() {
@Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
//運用反射執行目標對象方法
Object returnValue = method.invoke(target, args);
return returnValue;
}
}
);
}
}
複製代碼
public static void main(String[] args) {
// 目標對象
IUserDao target = new UserDao();
System.out.println(target.getClass());
// 給目標對象,建立代理對象
IUserDao proxy = (IUserDao) new UserDaoProxy(target).getProxyInstance();
proxy.save();
}
複製代碼