滴滴正式提交赴美上市申請:全球年活躍使用者達 4.93 億
阿新 • • 發佈:2021-06-11
動態代理實現
介面
public interface People {
public int eat();
}
被代理目標
public class User implements People{
@Override
public int eat() {
System.out.println("吃飯");
return 12;
}
}
通過實現被代理目標類的介面,並在生成的代理物件中執行需要被代理的方法,並額外新增自己需要的步驟
User user = new User(); People proxyInstance = (People) Proxy.newProxyInstance(user.getClass().getClassLoader(), user.getClass().getInterfaces(), (proxy, method, args2) -> { if (method.getName().equals("eat")) { System.out.println("代理開啟"); Object invoke = method.invoke(user, args2);//執行被代理方法 System.out.println("代理關閉"); return invoke;//返回被代理方法的返回值 }else { return method.invoke(user,args2); } });
user.getClass().getClassLoader():生成代理物件使用哪個類裝載器【一般我們使用的是被代理類的裝載器】
user.getClass().getInterfaces():生成哪個物件的代理物件,通過介面指定【指定要被代理類的介面】
method:當前執行的方法
cglib代理
cglib代理也叫子類代理,從記憶體中構建出一個子類來擴充套件目標物件的功能!通過繼承被代理目標類,從而增強其中的方法
被代理目標
public class User{ public int eat() { System.out.println("吃飯"); return 12; } } ```java public class ProxyFactory implements MethodInterceptor { //被代理目標物件,通過構造方法傳入 private Object target; public ProxyFactory(Object target){ this.target = target; } //獲取代理物件 public Object getProxyTarget() { 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("代理開啟"); Object invoke = method.invoke(target, objects); System.out.println("代理關閉"); return invoke; } }
執行程式碼
User proxyTarget = (User) new ProxyFactory(user).getProxyTarget(); System.out.println(proxyTarget.eat());
靜態代理和動態代理的區別
很明顯的是:
- 靜態代理需要自己寫代理類-->代理類需要實現與目標物件相同的介面
- 而動態代理不需要自己編寫代理類--->(是動態生成的)
使用靜態代理時:
-
靜態代理實現
public class ProxyUser implements People{ public User user = new User(); @Override public int eat() { System.out.println("代理開啟"); int eat = user.eat(); System.out.println("代理關閉"); return eat; } }
-
如果目標物件的介面有很多方法的話,那我們還是得一一實現,這樣就會比較麻煩
使用動態代理時:
- 代理物件的生成,是利用JDKAPI,動態地在記憶體中構建代理物件(需要我們指定建立 代理物件/目標物件 實現的介面的型別),並且會預設實現介面的全部方法。