国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

CGlib:AOP的另一種實(shí)現(xiàn)

開(kāi)發(fā) 后端
大家都知道,動(dòng)態(tài)代理能夠?qū)崿F(xiàn)AOP,但是它有一個(gè)缺點(diǎn),就是所有被代理的對(duì)象必須實(shí)現(xiàn)一個(gè)接口,否則就會(huì)報(bào)異常。那么如果被代理對(duì)象沒(méi)有實(shí)現(xiàn)接口那該如何實(shí)現(xiàn)AOP呢?當(dāng)然是能的,使用CGlib就可以實(shí)現(xiàn)。

 1、什么是CGlib

  CGlib是一個(gè)強(qiáng)大的,高性能,高質(zhì)量的Code生成類庫(kù)。它可以在運(yùn)行期擴(kuò)展Java類與實(shí)現(xiàn)Java接口。然這些實(shí)際的功能是asm所提供的,asm又是什么?Java字節(jié)碼操控框架,具體是什么大家可以上網(wǎng)查一查,畢竟我們這里所要討論的是cglib,cglib就是封裝了asm,簡(jiǎn)化了asm的操作,實(shí)現(xiàn)了在運(yùn)行期動(dòng)態(tài)生成新的class。可能大家還感覺(jué)不到它的強(qiáng)大,現(xiàn)在就告訴你。實(shí)際上CGlib為spring aop提供了底層的一種實(shí)現(xiàn);為hibernate使用cglib動(dòng)態(tài)生成VO/PO (接口層對(duì)象)。

  它的原理就是用Enhancer生成一個(gè)原有類的子類,并且設(shè)置好callback , 則原有類的每個(gè)方法調(diào)用都會(huì)轉(zhuǎn)成調(diào)用實(shí)現(xiàn)了MethodInterceptor接口的proxy的intercept() 函數(shù):
public Object intercept(Object o,Method method,Object[] args,MethodProxy proxy)
  在intercept()函數(shù)里,你可以在執(zhí)行Object result=proxy.invokeSuper(o,args);來(lái)執(zhí)行原有函數(shù),在執(zhí)行前后加入自己的東西,改變它的參數(shù),也可以瞞天過(guò)海,完全干別的。說(shuō)白了,就是AOP中的around advice。

  2、如何使用CGlib

  舉個(gè)例子:比如DAO層有對(duì)表的增、刪、改、查操作,如果要對(duì)原有的DAO層的增、刪、改、查增加權(quán)限控制的話,修改代碼是非常痛苦的。所以可以用AOP來(lái)實(shí)現(xiàn)。但是DAO層沒(méi)有使用接口,動(dòng)態(tài)代理不可用。這時(shí)候CGlib是個(gè)很好的選擇。

TableDao.java:

  1. package com.cglib; 
  2.   
  3.  public class TableDao { 
  4.      public void create(){ 
  5.          System.out.println("create() is running..."); 
  6.      } 
  7.      public void delete(){ 
  8.          System.out.println("delete() is running..."); 
  9.      } 
  10.      public void update(){ 
  11.          System.out.println("update() is running..."); 
  12.      } 
  13.      public void query(){ 
  14.          System.out.println("query() is running..."); 
  15.      } 
  16.  }

實(shí)現(xiàn)了MethodInterceptor接口的AuthProxy.java:用來(lái)對(duì)方法進(jìn)行攔截,增加方法訪問(wèn)的權(quán)限控制,這里只允許張三訪問(wèn)。

 

  1. package com.cglib; 
  2.   
  3.  import java.lang.reflect.Method; 
  4.   
  5.  import net.sf.cglib.proxy.MethodInterceptor; 
  6.  import net.sf.cglib.proxy.MethodProxy; 
  7.  //方法攔截器 
  8.  public class AuthProxy implements MethodInterceptor { 
  9.      private String userName; 
  10.      AuthProxy(String userName){ 
  11.          this.userName = userName; 
  12.      } 
  13.      //用來(lái)增強(qiáng)原有方法 
  14.      public Object intercept(Object arg0, Method arg1, Object[] arg2, 
  15.              MethodProxy arg3) throws Throwable { 
  16.          //權(quán)限判斷 
  17.          if(!"張三".equals(userName)){ 
  18.              System.out.println("你沒(méi)有權(quán)限!"); 
  19.              return null
  20.          } 
  21.          return arg3.invokeSuper(arg0, arg2); 
  22.      } 
  23.  } 

 

 

TableDAOFactory.java:用來(lái)創(chuàng)建TableDao的子類的工廠類

  1. package com.cglib; 
  2.   
  3.  import net.sf.cglib.proxy.Callback; 
  4.  import net.sf.cglib.proxy.Enhancer; 
  5.  import net.sf.cglib.proxy.NoOp; 
  6.   
  7.  public class TableDAOFactory { 
  8.      private static TableDao tDao = new TableDao();   
  9.      public static TableDao getInstance(){   
  10.          return tDao;   
  11.      }   
  12.      public static TableDao getAuthInstance(AuthProxy authProxy){   
  13.          Enhancer en = new Enhancer();  //Enhancer用來(lái)生成一個(gè)原有類的子類 
  14.          //進(jìn)行代理   
  15.          en.setSuperclass(TableDao.class);  
  16.          //設(shè)置織入邏輯 
  17.          en.setCallback(authProxy);   
  18.          //生成代理實(shí)例   
  19.          return (TableDao)en.create();   
  20.      }  
  21.   } 

測(cè)試類Client.java:

  1. package com.cglib; 
  2.   
  3.  public class Client { 
  4.   
  5.      public static void main(String[] args) {   
  6.  //        haveAuth();  
  7.          haveNoAuth(); 
  8.      }   
  9.      public static void doMethod(TableDao dao){   
  10.          dao.create();   
  11.          dao.query();   
  12.          dao.update();   
  13.          dao.delete();   
  14.      }   
  15.      //模擬有權(quán)限 
  16.      public static void haveAuth(){   
  17.          TableDao tDao = TableDAOFactory.getAuthInstance(new AuthProxy("張三"));   
  18.          doMethod(tDao);   
  19.      }   
  20.      //模擬無(wú)權(quán)限 
  21.      public static void haveNoAuth(){   
  22.          TableDao tDao = TableDAOFactory.getAuthInstance(new AuthProxy("李四"));   
  23.          doMethod(tDao);   
  24.      } 
  25.  } 

  這樣就能夠?qū)AO層的方法進(jìn)行權(quán)限控制了。但是如果又改需求了,要把DAO層的query方法讓所有用戶都可以訪問(wèn),而其他方法照樣有權(quán)限控制,該如何實(shí)現(xiàn)呢?這可難不倒我們了,因?yàn)槲覀兪褂昧薈Glib。當(dāng)然最簡(jiǎn)單的方式是去修改我們的方法攔截器,不過(guò)這樣會(huì)使邏輯變得復(fù)雜,且不利于維護(hù)。還好CGlib給我們提供了方法過(guò)濾器(CallbackFilter),CallbackFilte可以明確表明,被代理的類中不同的方法,被哪個(gè)攔截器所攔截。下面我們就來(lái)做個(gè)過(guò)濾器用來(lái)過(guò)濾query方法。

AuthProxyFilter.java:

  1. package com.cglib; 
  2.   
  3.  import java.lang.reflect.Method; 
  4.   
  5.  import net.sf.cglib.proxy.CallbackFilter; 
  6.  import net.sf.cglib.proxy.NoOp; 
  7.   
  8.  public class AuthProxyFilter implements CallbackFilter { 
  9.   
  10.      public int accept(Method arg0) { 
  11.          /* 
  12.           * 如果調(diào)用的不是query方法,則要調(diào)用authProxy攔截器去判斷權(quán)限 
  13.           */ 
  14.          if(!"query".equalsIgnoreCase(arg0.getName())){ 
  15.              return 0//調(diào)用第一個(gè)方法攔截器,即authProxy 
  16.          } 
  17.          /* 
  18.           * 調(diào)用第二個(gè)方法攔截器,即NoOp.INSTANCE,NoOp.INSTANCE是指不做任何事情的攔截器 
  19.           * 在這里就是任何人都有權(quán)限訪問(wèn)query方法,所以調(diào)用默認(rèn)攔截器不做任何處理 
  20.           */ 
  21.          return 1;   
  22.      } 
  23.   
  24.  } 

  至于為什么返回0或者1,注釋講的很詳細(xì)。

 

TableDAOFactory.java里添加如下方法:

  1. public static TableDao getAuthInstanceByFilter(AuthProxy authProxy){   
  2.        Enhancer en = new Enhancer();   
  3.        en.setSuperclass(TableDao.class);   
  4.         en.setCallbacks(new Callback[]{authProxy,NoOp.INSTANCE});  //設(shè)置兩個(gè)方法攔截器 
  5.         en.setCallbackFilter(new AuthProxyFilter());   
  6.        return (TableDao)en.create();   
  7.     }   
  8.  

  這里得注意,en.setCallbacks()方法里的數(shù)組參數(shù)順序就是上面方法的返回值所代表的方法攔截器,如果return 0則使用authProxy攔截器,return 1則使用NoOp.INSTANCE攔截器,NoOp.INSTANCE是默認(rèn)的方法攔截器,不做什么處理。

  下面在測(cè)試類中添加如下方法:

  1. //模擬權(quán)限過(guò)濾器 
  2.     public static void haveAuthByFilter(){   
  3.         TableDao tDao = TableDAOFactory.getAuthInstanceByFilter(new AuthProxy("張三"));   
  4.         doMethod(tDao);   
  5.         tDao = TableDAOFactory.getAuthInstanceByFilter(new AuthProxy("李四"));   
  6.         doMethod(tDao);   
  7.     }   

 

在main方法中調(diào)用該方法,程序運(yùn)行結(jié)果如下:

create() is running...
query() is running...
update() is running...
delete() is running...
你沒(méi)有權(quán)限!
query() is running...
你沒(méi)有權(quán)限!
你沒(méi)有權(quán)限!

  這樣的話,所有用戶都對(duì)query方法有訪問(wèn)權(quán)限了,而其他方法只允許張三訪問(wèn)。

責(zé)任編輯:周立方 來(lái)源: 博客園
相關(guān)推薦

2018-04-18 07:34:58

2014-09-17 14:37:06

2016-03-03 10:29:31

用戶信息改進(jìn)

2011-12-29 21:28:31

Metro UI

2010-07-21 16:23:09

運(yùn)行telnet程序

2023-06-18 23:19:17

ChatGPTPPT方式

2016-07-11 16:18:26

互聯(lián)網(wǎng)

2014-01-13 10:36:53

C++錯(cuò)誤

2019-01-02 08:04:29

GAN損失函數(shù)神經(jīng)網(wǎng)絡(luò)

2011-07-21 14:17:15

Ceylon

2013-09-30 10:13:08

IT女程序員

2013-10-21 15:11:15

OrmsqlOrm設(shè)計(jì)

2009-06-17 12:01:21

Linux

2015-07-28 13:36:04

2010-09-02 09:14:35

CSS浮動(dòng)

2009-06-17 09:05:05

Linux隱藏網(wǎng)絡(luò)鏈接命令

2021-10-20 12:20:08

深度學(xué)習(xí)AI賦能

2019-03-17 15:59:05

Android PAPIAPP

2013-09-12 14:26:47

百度云網(wǎng)盤

2010-06-09 16:17:20

TCP IP協(xié)議網(wǎng)絡(luò)故
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

天堂av在线一区| 亚洲精品中文在线| 青青青国产在线观看| 国产日韩在线不卡| 三区四区不卡| 成人午夜在线影院| 亚洲精品国产精品国自产观看浪潮 | 国产99一区视频免费| 午夜精品亚洲一区二区三区嫩草| 亚洲日韩欧美一区二区在线| 加勒比中文字幕精品| 97欧美精品一区二区三区| 国产一区二区三区免费| 99国内精品久久久久| 一本大道熟女人妻中文字幕在线 | 日韩精品视频在线观看一区二区三区| 91日韩一区二区三区| 综合久久一区| 大地资源网3页在线观看| 国产精品一区二区在线观看| 欧美日韩国产综合一区二区三区| 麻豆视频久久| 国产精品免费一区二区| 日韩高清欧美激情| 色中文字幕在线观看| 久久99精品国产麻豆婷婷洗澡| 国产美女主播在线| 亚洲欧美经典视频| 日韩精品影片| 最近2019中文字幕一页二页 | 国产河南妇女毛片精品久久久| 999福利在线视频| 色综合久久悠悠| 国产精品久久久久久一区二区三区| 一本大道熟女人妻中文字幕在线 | 色婷婷亚洲精品| aaa在线观看| 一区二区传媒有限公司| 国产视频精品久久久| 国产精品乱码人人做人人爱| 美女被久久久| 都市激情久久| 国产小视频精品| 亚洲激情一区二区| 欧美激情2020午夜免费观看| 1024国产精品| 国产精品原创视频| 国产真实生活伦对白| 狠狠操在线视频| 成人毛片一区二区| 97久久夜色精品国产九色 | 午夜网站在线观看| 不卡影院一区二区| 国产欧美一区二区在线播放| 欧美日韩成人网| 色欧美乱欧美15图片| 日韩黄色影片| 奇米影视亚洲色图| 性欧美办公室18xxxxhd| 日韩一级免费一区| 国产精品欧美久久久久一区二区 | 久久香蕉频线观| 夜夜嗨av一区二区三区中文字幕| 欧美在线高清| 日本黄色免费在线| 在线视频尤物| 91日韩视频在线观看| 波多野结衣家庭教师视频| 国产精品久久久亚洲| 久久韩国免费视频| 伊人久久久久久久久久久久久 | 午夜视频一区二区三区| 77thz桃花论族在线观看| 秋霞成人午夜鲁丝一区二区三区| 免费视频一区| 自拍偷拍21p| 日韩成人av一区| 亚洲人亚洲人色久| 日本三级免费网站| 亚洲欧洲在线播放| 热久久一区二区| 蜜桃av成人| 国外色69视频在线观看| 免费观看日韩av| mm131午夜| 亚洲精品中文字幕女同| 久久精品国产亚洲a| 天堂资源最新在线| 日韩免费观看在线观看| 成人av在线网| 在线成人视屏| 久久精品视频16| 欧美一区二区三区公司| 91蝌蚪精品视频| 欧美视频免费看欧美视频| 亚洲色图五月天| 成人免费看的视频| 另类视频一区二区三区| 男女爱爱免费网站| 日韩亚洲欧美中文三级| 四虎成人精品永久免费av九九| 亚洲国产成人精品无码区99| 国产精品成人一区二区艾草| 精品亚洲a∨一区二区三区18| 久久精品国产第一区二区三区最新章节| 中文字幕永久在线不卡| 日韩精品欧美专区| 在线电影欧美成精品| 一个色免费成人影院| 男人的天堂www| 国产精品亚洲аv天堂网| 欧美日韩在线综合| 欧美日韩亚洲一区| 日日躁夜夜躁aaaabbbb| 国产精品综合久久久| 日本精品一区二区三区在线播放视频| 欧美视频在线一区| 久久性色av| baoyu135国产精品免费| 在线免费观看视频黄| 成人午夜在线视频一区| 中文字幕一区二区三区不卡| 亚洲另类春色校园小说| 超碰97免费在线| 污视频网站免费在线观看| 91麻豆精品| 欧美一区亚洲| 国产精品一区二区久久不卡| 久久精品日韩一区二区三区| 精品日本美女福利在线观看| 亚洲激情视频网| 国产精品精品视频一区二区三区| 欧美最猛性xxxxx(亚洲精品)| 欧美性大战久久久久久久蜜臀| 亚洲免费中文| 久久国产主播| 玖玖精品视频| 亚洲成av人电影| 欧美激情护士| 国产三级视频在线| 久草福利资源在线视频| 男女h黄动漫啪啪无遮挡软件| 国产精品一区二区久久精品| 日韩精品有码在线观看| 成人免费在线观看入口| 亚洲综合二区| 成人精品久久| 精品一区二区三| 电影一区中文字幕| 在线播放毛片| 黄a在线观看| 中文字幕福利片| 三级视频网站在线| 理论片在线观看理伦片| 日韩精品一区二区三区色欲av| 久久综合一区二区三区| 亚洲影视九九影院在线观看| 欧美成人精品三级在线观看| 欧美多人乱p欧美4p久久| 国产三级精品三级| 久久精品视频免费观看| 久久伊人亚洲| 欧州一区二区| 丝袜美腿成人在线| 欧美日韩国产色综合一二三四| 亚洲欧美在线综合| 欧美专区18| 欧洲av在线精品| 日韩女优人人人人射在线视频| 女女百合国产免费网站| 色综合久久久久久久久五月| 日韩欧美精品一区二区三区经典| 手机成人在线| 艳色歌舞团一区二区三区| 成人一区二区三| 日本人视频jizz页码69| 成人一级片网站| 国产精品午夜久久久久久| www黄色在线| 爱福利视频一区二区| av影院在线免费观看| 久久精品视频免费观看| 久久免费99精品久久久久久| 欧美自拍电影| 成人综合在线网站| 国产精品久久久久高潮| 激情视频免费网站| 欧美日韩导航| 欧美日韩视频第一区| 久久亚洲国产精品日日av夜夜| 偷拍自拍在线| 国产精品免费看| 欧美日韩一本到| 精品日本一区二区三区在线观看| 四虎精品在线| 亚洲91网站| 一区二区三区四区在线播放| 成人自拍性视频| 中文字幕在线观看第一页| 亚洲一区区二区|