4.3 基于代理類(lèi)的Aop實(shí)現(xiàn)

從4.2節(jié)可知躲因,在Spring中默認(rèn)使用JDK動(dòng)態(tài)代理實(shí)現(xiàn)Aop編程帅戒。使用org.springframework.aop.framework.ProxyFactoryBean創(chuàng)建代理是Spring Aop實(shí)現(xiàn)的基本方式二驰。

1.通知類(lèi)型

在講解ProxyFactoryBean之前每强,先了解一下Spring的通知類(lèi)型玛荞。根據(jù)Spring中通知在目標(biāo)類(lèi)方法的連接點(diǎn)位置娇掏,可以分為6中如下類(lèi)型:

1.環(huán)繞通知(org.aopaliance.intercept.MethodInterceptor)是在目標(biāo)方法執(zhí)行前和執(zhí)行后實(shí)施增強(qiáng),可以用于日志記錄勋眯、事務(wù)處理等功能婴梧。

2.前置通知(org.apringframework.aop.MethodBeforeAdvice)
是在目標(biāo)方法執(zhí)行前實(shí)施增強(qiáng),可以用于權(quán)限管理等功能客蹋。

3.后置返回通知(org.springframework.aop.AfterReturningAdvice)是在目標(biāo)方法成功執(zhí)行后實(shí)施增強(qiáng)塞蹭,可應(yīng)用于關(guān)閉流、刪除臨時(shí)文件等功能讶坯。

4.后置(最終)通知(org.springframework.aop.AfterAdvice)是在目標(biāo)方法執(zhí)行后實(shí)施增強(qiáng)番电,與后置返回通知不同的是,不管是否發(fā)生異常都要執(zhí)行該通知辆琅,可應(yīng)用于釋放資源漱办。

5.異常通知(org.springframework.aop.ThrowsAdvice)是在方法拋出異常后實(shí)施增強(qiáng),可應(yīng)用于處理異常婉烟、記錄日志等功能娩井。

6.引入通知(org.springframework.aop.IntroductionInterceptor)是在目標(biāo)類(lèi)中添加一些新的方法和屬性,可應(yīng)用于修改目標(biāo)類(lèi)(增強(qiáng)類(lèi))隅很。

2.ProxyFactoryBean

ProxyFactoryBean是org.springframework.aop.framework.ProxyFactoryBean接口實(shí)現(xiàn)類(lèi)撞牢,F(xiàn)actoryBean負(fù)責(zé)實(shí)例化一個(gè)Bean實(shí)例率碾,ProxyFactoryBean負(fù)責(zé)為其他Bean實(shí)例創(chuàng)建代理實(shí)例。
下面通過(guò)一個(gè)實(shí)現(xiàn)環(huán)繞通知的實(shí)例演示Spring使用ProxyFactoryBean創(chuàng)建AoP代理的過(guò)程屋彪。

目錄結(jié)構(gòu)

img

2.1導(dǎo)入相關(guān)jar包

在核心jar包基礎(chǔ)上所宰,需要在向ch4應(yīng)用的/WEB-INF/lib目標(biāo)下導(dǎo)入jar包spring-aop-5.0.2.RELEASE.jar和aopalliance-1.0.jar(aopallication-1.0.jar是AoP聯(lián)盟提供的規(guī)范包)。

2.2創(chuàng)建切面類(lèi)

由于該類(lèi)實(shí)例實(shí)現(xiàn)環(huán)繞通知畜挥,所以切面類(lèi)需要實(shí)現(xiàn)org.aopaliance.intercept.MethodInterceptor接口仔粥。在src目錄下,創(chuàng)建一個(gè)spring.proxyfactorybean包蟹但,并在該包中創(chuàng)建切面類(lèi)MyAspect

MyAspect.java

package spring.proxyfactorybean;

import org.aopalliance.intercept.MethodInterceptor;
import org.aopalliance.intercept.MethodInvocation;
/**
 *切面類(lèi)
 */
public class MyAspect implements MethodInterceptor {

    @Override
    public Object invoke(MethodInvocation arg0) throws Throwable {
        // TODO Auto-generated method stub
        //增強(qiáng)方法
        check();
        except();
        //執(zhí)行目標(biāo)方法
        Object obj = arg0.proceed();
        //增強(qiáng)方法
        log();
        monitor();
        return obj;
    }
    public void check() {
        System.out.println("模擬權(quán)限控制");
    }
    
    public void except() {
        System.out.println("模擬異常處理");
    }
    
    public void log() {
        System.out.println("模擬日志記錄");
    }
    
    public void monitor() {
        System.out.println("性能檢測(cè)");
    }

}

2.3配置切面并指定助理

切面類(lèi)需要配置Bean實(shí)例躯泰,Spring容器才能識(shí)別為切面對(duì)象。在spring.proxyfactorybean包中华糖,創(chuàng)建配置文件applicationContext.xml麦向,
并在文件中配置切面和指定代理對(duì)象。

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       
http://www.springframework.org/schema/beans/spring-beans.xsd">
    <!-- 定義目標(biāo)對(duì)象 -->
    <bean id="testDao" class="dynamic.jdk.TestDaoImpl" />
    <!-- 創(chuàng)建一個(gè)切面 -->
    <bean id="myAspect" class="spring.proxyfactorybean.MyAspect" />
    <!-- 使用Spring代理工廠定義一個(gè)名為testDaoProxy的代理對(duì)象 -->
    <bean id="testDaoProxy" class="org.springframework.aop.framework.ProxyFactoryBean">
        <!-- 指定代理對(duì)象接口 -->
        <property name="proxyInterfaces" value="dynamic.jdk.TestDao" />
        <!-- 指定目標(biāo)對(duì)象 -->
        <property name="target" ref="testDao" />
        <!-- 指定切面,植入環(huán)繞通知 -->
        <property name="interceptorNames" value="myAspect" />
        <!-- 指定代理方法,true為指定CGLIB動(dòng)態(tài)代理客叉,默認(rèn)為false诵竭,指定JDK動(dòng)態(tài)代理 -->
        <property name="proxyTargetClass" value="true" />
    </bean>
</beans>

2.4創(chuàng)建測(cè)試類(lèi)

在spring.proxyfactorybean包中,創(chuàng)建測(cè)試類(lèi)ProxyFactoryBeanTest兼搏,在主方法中使用Spring容器獲取代理對(duì)象卵慰,并執(zhí)行目標(biāo)方法。

ProxyFactoryBeanTest.java

package spring.proxyfactorybean;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import dynamic.jdk.TestDao;

public class ProxyfactoryBeanTest {

    public static void main(String[] args) {
        // TODO Auto-generated method stub
        ApplicationContext appCon = new ClassPathXmlApplicationContext("/spring/proxyfactorybean/applicationContext.xml");
        //從容器中,獲取增強(qiáng)后的目標(biāo)對(duì)象
        TestDao testDaoAdvice = (TestDao)appCon.getBean("testDaoProxy");
        //執(zhí)行方法
        testDaoAdvice.save();
        System.out.println("==============");
        testDaoAdvice.modify();
        System.out.println("==============");
        testDaoAdvice.delete();
    }

}

運(yùn)行結(jié)果

img

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末佛呻,一起剝皮案震驚了整個(gè)濱河市裳朋,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌吓著,老刑警劉巖鲤嫡,帶你破解...
    沈念sama閱讀 211,948評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異绑莺,居然都是意外死亡泛范,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,371評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)紊撕,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)罢荡,“玉大人,你說(shuō)我怎么就攤上這事对扶∏裕” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 157,490評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵浪南,是天一觀的道長(zhǎng)笼才。 經(jīng)常有香客問(wèn)我,道長(zhǎng)络凿,這世上最難降的妖魔是什么骡送? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,521評(píng)論 1 284
  • 正文 為了忘掉前任昂羡,我火速辦了婚禮,結(jié)果婚禮上摔踱,老公的妹妹穿的比我還像新娘虐先。我一直安慰自己,他們只是感情好派敷,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,627評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布蛹批。 她就那樣靜靜地躺著,像睡著了一般篮愉。 火紅的嫁衣襯著肌膚如雪腐芍。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,842評(píng)論 1 290
  • 那天试躏,我揣著相機(jī)與錄音猪勇,去河邊找鬼。 笑死颠蕴,一個(gè)胖子當(dāng)著我的面吹牛埠对,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播裁替,決...
    沈念sama閱讀 38,997評(píng)論 3 408
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼貌笨!你這毒婦竟也來(lái)了弱判?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,741評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤锥惋,失蹤者是張志新(化名)和其女友劉穎昌腰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體膀跌,經(jīng)...
    沈念sama閱讀 44,203評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡遭商,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,534評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了捅伤。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片劫流。...
    茶點(diǎn)故事閱讀 38,673評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖丛忆,靈堂內(nèi)的尸體忽然破棺而出祠汇,到底是詐尸還是另有隱情,我是刑警寧澤熄诡,帶...
    沈念sama閱讀 34,339評(píng)論 4 330
  • 正文 年R本政府宣布可很,位于F島的核電站,受9級(jí)特大地震影響凰浮,放射性物質(zhì)發(fā)生泄漏我抠。R本人自食惡果不足惜苇本,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,955評(píng)論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望菜拓。 院中可真熱鬧瓣窄,春花似錦、人聲如沸尘惧。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,770評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)喷橙。三九已至啥么,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間贰逾,已是汗流浹背悬荣。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,000評(píng)論 1 266
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留疙剑,地道東北人氯迂。 一個(gè)月前我還...
    沈念sama閱讀 46,394評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像言缤,于是被迫代替她去往敵國(guó)和親嚼蚀。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,562評(píng)論 2 349

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

  • AOP的全稱(chēng)是Aspect-Oriented Programming.即面向切面編程管挟,也稱(chēng)為面向方面編程轿曙,它是面向...
    飛鷯閱讀 770評(píng)論 0 0
  • **** AOP 面向切面編程 底層原理 代理!Fⅰ导帝! 今天AOP課程1、 Spring 傳統(tǒng) AOP2穿铆、 Spri...
    luweicheng24閱讀 1,359評(píng)論 0 1
  • 概述 Spring是什么您单? Spring是一個(gè)開(kāi)源框架,為了解決企業(yè)應(yīng)用開(kāi)發(fā)的復(fù)雜性而創(chuàng)建的荞雏,但是現(xiàn)在已經(jīng)不止于企...
    瑯筑閱讀 1,158評(píng)論 2 8
  • 什么是AOP 面向切面編程(AOP)和面向?qū)ο缶幊蹋∣OP)類(lèi)似虐秦,也是一種編程模式。Spring AOP 是基于 ...
    小波同學(xué)閱讀 298評(píng)論 0 0
  • 本博中關(guān)于spring的文章:Spring IOC和AOP原理凤优,Spring事務(wù)原理探究羡疗,Spring配置文件屬性...
    Maggie編程去閱讀 4,098評(píng)論 0 34