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

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

        兩種方式為: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號
        主站蜘蛛池模板: 精品中文高清欧美| 日本精品夜色视频一区二区| 国产精品午夜国产小视频| 亚洲欧美日韩国产精品专区| 国产精品成人观看视频| 996久久国产精品线观看| 亚洲精品国偷自产在线| 国产精品小黄鸭一区二区三区| 99国产精品久久久久久久成人热| 中文字幕一区二区三区日韩精品| 国产成人精品高清不卡在线 | 中国精品18videosex性中国| 国产精品嫩草影院一二三区| 99久久精品毛片免费播放| 亚洲精品午夜无码专区| 久久久精品无码专区不卡| 国产精品99久久精品爆乳| 日本精品久久久中文字幕| 国产成人精品无码片区在线观看| 无码人妻精品一区二区三 | 夜夜精品无码一区二区三区 | 国产午夜福利精品一区二区三区| 四虎影视永久在线精品免费| 精品国产一区二区三区AV性色| 性色精品视频网站在线观看 | 亚洲国产精品毛片av不卡在线| 精品99久久aaa一级毛片| 国产精品天干天干在线综合| 91亚洲精品麻豆| 中文字幕精品视频| 在线精品国产一区二区| 777国产盗摄偷窥精品0OOO| 久久精品国产亚洲欧美| 国产精品网址你懂的| 麻豆精品久久精品色综合| 青青青青久久精品国产h| 3级黄性日本午夜精品| 国产精品无码久久久久| 久久国产热这里只有精品| 午夜成人精品福利网站在线观看 | 黄床大片免费30分钟国产精品|