靜態代理與動態代理模式
阿新 • • 發佈:2021-01-21
1.靜態代理模式
-
靜態代理角色分析
抽象角色:一般由介面或抽象類來實現
真實角色:實現抽象角色的實現類,也是被代理的角色
代理角色:代理真是角色,一般會做一些附屬操作,比如記錄日誌等
客戶:使用代理角色進行一下操作
-
抽象角色
public interface UserService { void add(); void update(); void query(); void delete(); }
-
真實角色
public class UserServiceImpl implements UserService{ @Override public void add() { System.out.println("添加了一個使用者!"); } @Override public void update() { System.out.println("修改了一個使用者!"); } @Override public void query() { System.out.println("查詢了一個使用者!"); } @Override public void delete() { System.out.println("刪除了一個使用者!"); } }
-
代理角色
public class UserServicePoxy implements UserService { private UserService userService; public void setUserService(UserService userService) { this.userService = userService; } @Override public void add() { userService.add(); addLog("新增"); } @Override public void update() { userService.update(); addLog("修改"); } @Override public void query() { userService.query(); addLog("查詢"); } @Override public void delete() { userService.delete(); addLog("刪除"); } public void addLog(String methodName){ System.out.println("【日誌】"+methodName+"一個使用者!"); } }
-
客戶
public class MyTest { public static void main(String[] args) { //建立真實物件 UserService userService = new UserServiceImpl(); //建立代理 UserServicePoxy userServicePoxy = new UserServicePoxy(); //將真實物件交給代理 userServicePoxy.setUserService(userService); //用代理去新增使用者 userServicePoxy.add(); } }
2.動態代理模式
動態代理的角色與靜態代理一樣,只不過動態代理的代理類是動態生成的。動態代理分為基於介面的動態代理和基於類的動態代理。
- 基於介面的動態代理—JDK動態代理;
- 基於類的動態代理—cglib;
- 現在用的比較多的是用javasist來生成動態代理。
JDK動態代理需要了解兩個類InvocationHandler和Proxy。
InvocationHander[程式處理]
其invoke方法是代理角色在呼叫真實角色的處理方法時,會呼叫該方法,並用反射的方式實現真實角色的方法。
Proxy 代理
public static Object newProxyInstance(ClassLoader loader,
Class<?>[] interfaces,
InvocationHandler h)
生成代理角色,loader 類載入器,interfaces 抽象角色的class物件集合,h 處理程式的實體類
- 抽象角色
public interface UserService {
void add();
void update();
void query();
void delete();
}
-
真實角色
public class UserServiceImpl implements UserService { @Override public void add() { System.out.println("添加了一個使用者!"); } @Override public void update() { System.out.println("修改了一個使用者!"); } @Override public void query() { System.out.println("查詢了一個使用者!"); } @Override public void delete() { System.out.println("刪除了一個使用者!"); } }
-
動態代理處理程式
/** * 代理例項的呼叫處理程式介面實現類 */ public class ProxyInvocationHandler implements InvocationHandler { private Object target; public void setTarget(Object target) { this.target = target; } //代理角色呼叫真實角色中的方法時會呼叫invoke方法來實現真實角色中的方法(反射的思想) @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { log(method.getName()); Object result = method.invoke(target,args); return result; } //生成代理類 public Object getProxy(){ return Proxy.newProxyInstance(this.getClass().getClassLoader(),target.getClass().getInterfaces(),this); } void log(String msg){ System.out.println("執行了"+msg+"方法!"); } }
-
客戶端
public static void main(String[] args) { //建立真實角色 UserService userService = new UserServiceImpl(); //建立處理程式 ProxyInvocationHandler pih = new ProxyInvocationHandler(); //將真實角色注入到處理程式中,為代理做準備 pih.setTarget(userService); //生成代理類 UserService proxy = (UserService) pih.getProxy(); //執行新增方法 其實是通過處理程式中的invoke呼叫真實角色中的add方法 proxy.add(); }
-
執行結果