站長資訊網
        最全最豐富的資訊網站

        動態代理的兩種方式是什么

        兩種方式為:1、JDK動態代理,利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理;2、CGLIB動態代理,利用asm開源包,對代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。

        動態代理的兩種方式是什么

        本教程操作環境:windows7系統、java8版、DELL G3電腦。

        動態代理是反射的一個非常重要的應用場景。動態代理常被用于一些 Java 框架中。例如 Spring 的 AOP ,Dubbo 的 SPI 接口,就是基于 Java 動態代理實現的。

        動態代理的方式有兩種:

        • JDK動態代理:利用反射機制生成一個實現代理接口的匿名類,在調用具體方法前調用InvokeHandler來處理。

        • CGLIB動態代理:利用ASM(開源的Java字節碼編輯庫,操作字節碼)開源包,將代理對象類的class文件加載進來,通過修改其字節碼生成子類來處理。

        區別:JDK代理只能對實現接口的類生成代理;CGlib是針對類實現代理,對指定的類生成一個子類,并覆蓋其中的方法,這種通過繼承類的實現方式,不能代理final修飾的類。

        強制使用CGlib

        <!-- proxy-target-class="false"默認使用JDK動態代理 --> <aop:aspectj-autoproxy proxy-target-class="true"/>  <aop-config proxy-target-class="true"> <!-- 切面詳細配置 --> </aop-config>

        具體代碼示例:

        /**  * 目標接口類  */ public interface UserManager {         public void addUser(String id, String password);         public void delUser(String id);     }
        /**  * 接口實現類  */ public class UserManagerImpl implements UserManager {              @Override     public void addUser(String id, String password) {             System.out.println("調用了UserManagerImpl.addUser()方法!");     }              @Override     public void delUser(String id) {             System.out.println("調用了UserManagerImpl.delUser()方法!");     }     }
        /**  * JDK動態代理類  */ public class JDKProxy implements InvocationHandler {              // 需要代理的目標對象     private Object targetObject;              public Object newProxy(Object targetObject) {         // 將目標對象傳入進行代理             this.targetObject = targetObject;         // 返回代理對象          return Proxy.newProxyInstance(targetObject.getClass().getClassLoader(), targetObject.getClass().getInterfaces(), this);     }              // invoke方法     @Override     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {         // 進行邏輯處理的函數         checkPopedom();         Object ret = null;         // 調用invoke方法         ret = method.invoke(targetObject, args);         return ret;     }              private void checkPopedom() {         // 模擬檢查權限            System.out.println("檢查權限:checkPopedom()!");         }     }
        /**  * CGlib動態代理類  */  public class CGLibProxy implements MethodInterceptor {              // CGlib需要代理的目標對象     private Object targetObject;          public Object createProxyObject(Object obj) {         this.targetObject = obj;         Enhancer enhancer = new Enhancer();         enhancer.setSuperclass(obj.getClass());         enhancer.setCallback(this);         Object proxyObj = enhancer.create();         return proxyObj;     }          @Override     public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {         Object obj = null;         // 過濾方法         if ("addUser".equals(method.getName())) {             // 檢查權限             checkPopedom();         }         obj = method.invoke(targetObject, args);         return obj;     }              private void checkPopedom() {         System.out.println("檢查權限:checkPopedom()!");     } }
        /**  * 測試類  */ public class ProxyTest {          public static void main(String[] args) {         UserManager userManager = (UserManager)new CGLibProxy().createProxyObject(new UserManagerImpl());         System.out.println("CGLibProxy:");         userManager.addUser("tom", "root");         System.out.println("JDKProxy:");         JDKProxy jdkProxy = new JDKProxy();         UserManager userManagerJDK = (UserManager)jdkProxy.newProxy(new UserManagerImpl());         userManagerJDK.addUser("tom", "root");     } }
        // 運行結果 CGLibProxy: 檢查權限checkPopedom()! 調用了UserManagerImpl.addUser()方法! JDKProxy: 檢查權限checkPopedom()! 掉用了UserManagerImpl.addUser()方法!

        總結:

        1、JDK代理使用的是反射機制實現aop的動態代理,CGLIB代理使用字節碼處理框架asm,通過修改字節碼生成子類。所以jdk動態代理的方式創建代理對象效率較高,執行效率較低,cglib創建效率較低,執行效率高;

        2、JDK動態代理機制是委托機制,具體說動態實現接口類,在動態生成的實現類里面委托hanlder去調用原始實現類方法,CGLIB則使用的繼承機制,具體說被代理類和代理類是繼承關系,所以代理類是可以賦值給被代理類的,如果被代理類有接口,那么代理類也可以賦值給接口。

        (推薦教程:java入門教程)

        贊(0)
        分享到: 更多 (0)
        網站地圖   滬ICP備18035694號-2    滬公網安備31011702889846號
        主站蜘蛛池模板: 久久99国产精品二区不卡| 国产精品无码无需播放器| 亚洲国产精品嫩草影院在线观看| 国产精品一级片| 日韩精品无码一区二区三区| 精品久久久无码中文字幕天天 | 亚洲AⅤ永久无码精品AA| 久久久久四虎国产精品| 精品无码国产一区二区三区AV| 亚洲精品97久久中文字幕无码| 国产一区二区三区精品视频| 8050免费午夜一级国产精品| 国产精品91在线| 久久精品国产亚洲77777| 亚洲日韩精品一区二区三区| 午夜精品久久久久久影视777 | AV无码精品一区二区三区| 日韩精品专区AV无码| 亚洲精品成人区在线观看| 精品无码久久久久久久久久| 国产精品va在线观看无码| 欧美成人精品一级高清片| 久久se精品一区精品二区| 国产精品成人观看视频国产| 99在线精品视频| 99国产精品国产精品九九| 国产精品福利自产拍在线观看| 久久精品人人做人人爽97| 中文无码久久精品| 中文字幕久久精品| 一本色道久久综合亚洲精品| 中文字幕久久精品无码| 亚洲精品字幕在线观看| 无码人妻丰满熟妇精品区| 亚洲国产精品一区二区第一页| 久久婷婷国产综合精品| 久久精品午夜一区二区福利| 久久精品www人人爽人人| 国内精品久久久人妻中文字幕| 国产精品亲子乱子伦xxxx裸| 91麻豆精品国产|