public interface Interface_ { public void do(); }
public class Object_ implements Interface_{ @Override public void do() { System.out.println("do"); } }
public class Object_Agent implements Interface_{ private Object_ object_; public Object_Agent(Object_ object_) { this.object_ = object_; } @Override public void do() { System.out.println("enhance"); object_.do(); } public static void main(String[] args) { Object_ object_ = new Object_(); Object_Agent agent = new Object_Agent(object_); agent.do(); } }
- JDK動態代理是基於接口的方式,代理類和目標類都實現同一個接口。
- CGLib動態代理是代理類去繼承目標類,而後重寫其中目標類的方法。
public interface Interface_ { public void do(); }
public class Object_ implements Interface_{ @Override public void do() { System.out.println("do"); } }
public class InvocationHandlerImpl implements InvocationHandler{ private Object object; public InvocationHandlerImpl(Object object) { this.object = object; } public Object invoke(Object proxy, Method method, Object[] args) throws Throwable { System.out.println("enhance"); Object object = method.invoke(object, args); return object; } }
public class DynamicProxyDemonstration { public static void main(String[] args) { Interface_ object_ = new Object_(); InvocationHandler handler = new InvocationHandlerImpl(object_); ClassLoader loader = object_.getClass().getClassLoader(); Class[] interfaces = object_.getClass().getInterfaces(); Interface_ object__ = (Interface_) Proxy.newProxyInstance(loader, interfaces, handler); object__.do(); } }
<dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>2.2.2</version> </dependency>
public class Object_{ public void do() { System.out.println("do"); } }
public class MyMethodInterceptor implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable { System.out.println("enhance"); Object object = proxy.invokeSuper(obj, args); return object; } }
public class CgLibProxy { public static void main(String[] args) { //建立Enhancer對象,相似於JDK動態代理的Proxy類,下一步就是設置幾個參數 Enhancer enhancer = new Enhancer(); //設置目標類的字節碼文件 enhancer.setSuperclass(Object_.class); //設置回調函數 enhancer.setCallback(new MyMethodInterceptor()); //建立加運行 Object_ proxyObject_ = (Object_)enhancer.create(); proxyObject_.do(); } }
通常寫代碼:html
@Autowired UserService userService;
出錯代碼:java
@Autowired UserServiceImpl userService;
JDK 動態代理是基於接口的,代理生成的對象只能賦值給接口變量。git
而 CGLIB 就不存在這個問題。由於 CGLIB 是經過生成子類來實現的,代理對象不管是賦值給接口仍是實現類這二者都是代理對象的父類。github
[1].CGLib動態代理spring
[2].java反射和代理ide
[3].驚人!Spring5 AOP 默認使用Cglib? 從現象到源碼深度分析函數
本文做者: Both Savage本文連接: https://bothsavage.github.io/...性能
版權聲明: 本博客全部文章除特別聲明外,均採用 BY-NC-SA 許可協議。轉載請註明出處!測試