#千鋒逆戰(zhàn)# 動(dòng)態(tài)代理AOP(1)

動(dòng)態(tài)代理

  1. jdk代理方式

    1. 新建接口

      • public interface IUserService<T> {
        
            /**
             * 獲取所有的用戶對(duì)象列表
             * @return
             */
            List<T> getAllUser();
        
            /**
             * 保存用戶
             * @param user
             * @return
             */
            boolean saveUser(T user);
        
            /**
             * 根據(jù)用戶uid刪除該uid對(duì)應(yīng)的用戶信息
             * @param uid
             * @return
             */
            boolean deleteUser(int uid);
        
            /**
             * 更新指定用戶信息
             * @param obj
             * @return
             */
            boolean updateUser(T obj);
        }
        
    2. 實(shí)現(xiàn)接口

    3. 實(shí)現(xiàn)代理方法

      • public class UserFactory {
        
            public static IUserService getUserService(){
        
                IUserService us = new UserservcieImpl();//被代理的對(duì)象
        
                MyAspect ma = new MyAspect();//需要添加的代理
        
                /**
                 * @param UserFactory.class.getClassLoader() 類加載器,用來加載代理類
                 * @param us.getClass().getInterfaces() 被代理的接口
                 * @param new InvocationHandler() 內(nèi)部類 重寫invoke方法
                 */
                IUserService ius = (IUserService) Proxy.newProxyInstance(UserFactory.class.getClassLoader()
                        , us.getClass().getInterfaces(), new InvocationHandler() {
        
                    /**
                     * 代理對(duì)象調(diào)用的回掉方法
                     * @param proxy 代理對(duì)象
                     * @param method 被代理的方法
                     * @param args 被代理方法的參數(shù)列表對(duì)象
                     * @return 每個(gè)方法的最終返回值
                     * @throws Throwable
                     */
                    @Override
                    public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
        
                        ma.before();
        
                        Object obj = method.invoke(us, args);//原方法
        
                        ma.after();
        
                        return obj;
                    }
                });
        
                return ius;
            }
        }
        
  2. cglib代理方式

    1. 與jdk代理相似,代理方法有所不同

    2. 基本原理

      • 使用Enhancer生成原有類的子類,設(shè)置好回掉(callback),那么原有類的所有方法都會(huì)被攔截然后調(diào)用實(shí)現(xiàn)了MethodInterceptor的intercept()方法.
    • 提示:如果原方法是final類型的,則MethodInterceptor無法攔截
    1. 代理方法

      • public class UserFactory {
        
            /**
             * 使用Spring中的一個(gè)增強(qiáng)類來實(shí)現(xiàn)aop方式
             *      1.  創(chuàng)建Enhancer對(duì)象
             *      2.  設(shè)置增強(qiáng)類Enhancer的superClass
             *      3.  設(shè)置Enhancer對(duì)象的回調(diào)
             *      4.  通過eh對(duì)象的create()方法來得到指定的對(duì)象
             * @return
             */
            public static IUserService getUserService(){
                //  1.  創(chuàng)建Enhancer對(duì)象
                Enhancer eh = new Enhancer();
                //  2.  設(shè)置增強(qiáng)類Enhancer的superClass
                eh.setSuperclass(IUserService.class);
        
                IUserService<Object> us = new UserServiceImpl<>();//需要代理的對(duì)象
                MyAspect ma = new MyAspect();//
                //  3.  設(shè)置Enhancer對(duì)象的回調(diào)
                eh.setCallback(new MethodInterceptor() {
                    
                    /**
                    * Object o:被代理的對(duì)象
                    * Method method:被攔截的方法
                    * Object[] objects:被攔截的方法的參數(shù)們
                    * MethodProxy methodProxy:MethodProxy類型的被攔截方法
                    **/
                    @Override
                    public Object intercept(Object o, Method method, Object[] objects, MethodProxy methodProxy) throws Throwable {
        
                        ma.before();
        
                        Object obj = method.invoke(us, objects);
        
                        ma.after();
        
                        return obj;
                    }
                });
        
                //  4.  通過eh對(duì)象的create()方法來得到指定的對(duì)象
                IUserService<Object> ius = (IUserService<Object>) eh.create();
        
                return ius;
            }
        }
        

jdk代理方式與cglib代理方式的區(qū)別

  1. JDK代理只能對(duì)實(shí)現(xiàn)了接口的類生成代理,而CGLIB是通過繼承的方式實(shí)現(xiàn)代理也可以為實(shí)現(xiàn)了接口的類強(qiáng)制使用
  2. JDK代理在使用次數(shù)較少時(shí)效率高于CGLIB代理,當(dāng)大量使用時(shí)CGLIB代理更勝一籌.但隨著jdk版本的升級(jí),JDK代理效率不斷提升,到j(luò)dk8時(shí)高于CGLIB代理

spring框架中的動(dòng)態(tài)代理方式

  1. 創(chuàng)建被代理類接口并實(shí)現(xiàn)接口

  2. 創(chuàng)建代理類,并實(shí)現(xiàn)MethodInterceptor接口

    • 重寫invoke方法

    •  @Override
          public Object invoke(MethodInvocation invocation) throws Throwable {
        
              before();
        
              //  業(yè)務(wù)處理方法的調(diào)用
              Object obj = invocation.proceed();
        
              after();
        
              return obj;
          }
      
  3. 配置beans.xml

    • 分別配置被代理類bean(id="us")和代理類bean(id="my")

    • 配置代理工廠

      • <!--
                ProxyFactoryBean代理的FactoryBean對(duì)象运悲,我們現(xiàn)在要代理的是us
                    包含四個(gè)屬性注入:
                        1.  interfaces: 接口對(duì)象們
                            <list>
                                <value>com.qfedu.aop03.IUserService</value>
                                <value>com.qfedu.aop03.IUserService</value>
                                <value>com.qfedu.aop03.IUserService</value>
                            </list>
                        2.  target:目標(biāo)對(duì)象绸栅,哪個(gè)對(duì)象將被以代理的方式創(chuàng)建
                        3.  interceptorNames:攔截對(duì)象的名稱洛勉,自定義的MethodInterceptor對(duì)象棒厘,注意它的包結(jié)構(gòu)組成
                        4.  optimize:boolean類型的值:
                                true:強(qiáng)制使用cglib的動(dòng)態(tài)代理方式
                                false:使用jdk自帶的動(dòng)態(tài)代理
                                cglib:code generation library纵穿,代碼生成庫,性能更高
            -->
            <bean id="proxy" class="org.springframework.aop.framework.ProxyFactoryBean">
                <property name="interfaces" value="com.qfedu.aop03.IUserService" />
                <property name="target" ref="us" />
                <property name="interceptorNames" value="my" />
                <property name="optimize" value="true" />
            </bean>
        
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末奢人,一起剝皮案震驚了整個(gè)濱河市谓媒,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌何乎,老刑警劉巖句惯,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異支救,居然都是意外死亡抢野,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門各墨,熙熙樓的掌柜王于貴愁眉苦臉地迎上來指孤,“玉大人,你說我怎么就攤上這事贬堵∈研” “怎么了?”我有些...
    開封第一講書人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵黎做,是天一觀的道長叉跛。 經(jīng)常有香客問我,道長引几,這世上最難降的妖魔是什么昧互? 我笑而不...
    開封第一講書人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮伟桅,結(jié)果婚禮上敞掘,老公的妹妹穿的比我還像新娘。我一直安慰自己楣铁,他們只是感情好玖雁,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著盖腕,像睡著了一般赫冬。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上溃列,一...
    開封第一講書人閱讀 49,760評(píng)論 1 289
  • 那天劲厌,我揣著相機(jī)與錄音,去河邊找鬼听隐。 笑死补鼻,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播风范,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼咨跌,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了硼婿?” 一聲冷哼從身側(cè)響起锌半,我...
    開封第一講書人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎寇漫,沒想到半個(gè)月后刊殉,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡猪腕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年冗澈,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了钦勘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片陋葡。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖彻采,靈堂內(nèi)的尸體忽然破棺而出腐缤,到底是詐尸還是另有隱情,我是刑警寧澤肛响,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布岭粤,位于F島的核電站,受9級(jí)特大地震影響特笋,放射性物質(zhì)發(fā)生泄漏剃浇。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一猎物、第九天 我趴在偏房一處隱蔽的房頂上張望虎囚。 院中可真熱鬧,春花似錦蔫磨、人聲如沸淘讥。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽蒲列。三九已至,卻和暖如春搀罢,著一層夾襖步出監(jiān)牢的瞬間蝗岖,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來泰國打工榔至, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留抵赢,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像瓣俯,于是被迫代替她去往敵國和親杰标。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容