實現一個Cglib代理Demo
阿新 • • 發佈:2018-11-15
Cglib動態代理採用的是建立目標類的子類的方式。優點:不用實現額外介面,只操作我們關心類,高效能。
package jesse.test; import java.lang.reflect.Method; import net.sf.cglib.proxy.Enhancer; import net.sf.cglib.proxy.MethodInterceptor; import net.sf.cglib.proxy.MethodProxy; class Father{ public void sayHello(){ System.out.println("this is father"); } } interface Person{ void speak(); void walk(); } class Student extends Father implements Person{ public void study(){ System.out.println("i am student."); } @Override public void speak() { System.out.println("i am student ,i can speak"); } @Override public void walk() { System.out.println("i am student ,i can walk"); } } class MyMethodInterceptor implements MethodInterceptor{ @Override public Object intercept(Object obj, Method method, Object[] arg, MethodProxy proxy) throws Throwable { System.out.println("Before: "+ method); Object object = proxy.invokeSuper(obj, arg); System.out.println("After: "+method); return object; } } public class MyCglibProxy { public static void main(String[] args) { //可以指定 CGLIB 將動態生成的代理類儲存至指定的磁碟路徑下 //System.setProperty(DebuggingClassWriter.DEBUG_LOCATION_PROPERTY,"本地磁碟路徑"); Enhancer enhancer = new Enhancer(); enhancer.setSuperclass(Student.class); enhancer.setCallback(new MyMethodInterceptor()); Student student = (Student)enhancer.create(); student.sayHello(); student.speak(); student.walk(); student.study(); } } /** * 就是隻能為介面中的方法完成代理,而委託類自己的方法或者父類中的方法都不可能被代理。 * CGLIB 應運而生,它是一個高效能的,底層基於 ASM 框架的一個程式碼生成框架,它完美的解決了 JDK 版本的 * 動態代理只能為介面方法代理的單一性不足問題 * * Student 是我們需要代理的委託型別,結果生成的代理類就直接繼承了委託類。 * 這一個小設計就完美的解決了 JDK 動態代理那個單一代理的缺陷,繼承了委託類,就可以反射出委託類介面中的所有方法, * 父類中的所有方法,自身定義的所有方法,完成這些方法的代理就完成了對委託類所有方法的代理。 * * 說明:cglib生成代理是通過位元組碼生成的子類作為代理類,因此不能對private final方法代理; * * 比較: * CGLib動態代理建立代理例項速度慢,但是執行速度快;JDK動態代理建立例項速度快,但是執行速度慢。如果例項是單例的, * 推薦使用CGLib方式動態代理,反之則使用JDK方式進行動態代理。Spring的例項預設是單例,所以這時候使用CGLib效能高。 * */
<!-- cglib --> <dependency> <groupId>cglib</groupId> <artifactId>cglib</artifactId> <version>3.2.5</version> </dependency>