java靜態代理、動態代理、cglib代理
阿新 • • 發佈:2020-11-16
首先定義一個介面:
public interface AdminControl { void find(); void update(); void add(); }
實現類:
public class AdminControlImpl implements AdminControl{ public void find() { System.out.println("查詢所有管理員資訊"); } public void update() { System.out.println("修改管理員資訊"); }public void add() { System.out.println("增加管理員資訊"); } }
靜態代理
public class AdminControlProxy implements AdminControl{ private AdminControl adminControl; public AdminControlProxy(AdminControl adminControl){ this.adminControl = adminControl; } public void find() { System.out.println("進入方法find"); adminControl.find(); System.out.println("退出方法find"); } public void update() { System.out.println("進入方法update"); adminControl.update(); System.out.println("退出方法update"); } }
代理模式可以在不修改被代理物件的基礎上,通過擴充套件代理類,進行一些功能的附加與增強.
靜態代理缺點:
1.假設系統中需要代理的service過多,那麼就會建立很多代理物件
2.假設代理的service方法改變,那麼相應的代理物件也會改變
動態代理
- proxy 代理物件
- method 代理物件呼叫的方法
- args 呼叫的方法中的引數
public class AdminControlInvocation implements InvocationHandler { private Object object; public AdminControlInvocation(Object object){ this.object = object; } @Override public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("進入方法"+method.getName()); Object object = method.invoke(object,args); System.out.println("退出方法"+method.getName()); return object; } }
假設代理的物件沒有介面,那麼就不能使用動態代理
cglib代理
首先引入依賴
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.3.0</version> </dependency>
程式碼
public class AdminControlCglibProxy implements MethodInterceptor { private Object object; public AdminControlCglibProxy(Object object){ this.object = object; } public Object getProxyInstance(){ Enhancer enhancer = new Enhancer(); // 設定代理類的父類 enhancer.setSuperclass(target.getClass()); enhancer.setCallback(this); return enhancer.create(); } @Override public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable { System.out.println("進入方法"+method.getName()); Object object = method.invoke(object,objects); System.out.println("退出方法"+method.getName()); return object; } }
對於一個沒有介面的類,使用cglib代理,前提,該類必須可以被繼承,方法不能為final、static。
cglib是採用動態建立子類的方法來代理