AOP面向切面編程

AOP面向切面編程

aop:面向切面編程,采取的是橫向抽取機(jī)制仇哆,取代了傳統(tǒng)的縱向繼承體系重復(fù)性的代碼酪我,簡單的來說就是拓展功能的時(shí)候可以不通過修改源碼實(shí)現(xiàn)。

舉個(gè)例子,在最原始的機(jī)制中把沼,當(dāng)我們要給一個(gè)類中的方法添加某個(gè)功能的時(shí)候啊易,比如為了后期維護(hù)系統(tǒng)方便,要給方法添加日志打印的功能饮睬,這個(gè)時(shí)候只能通過修改源代碼的方式實(shí)現(xiàn)租谈,當(dāng)系統(tǒng)中有很多類的時(shí)候,修改源代碼就顯得費(fèi)時(shí)費(fèi)力了捆愁。

這個(gè)時(shí)候可以采用縱向的抽取機(jī)制割去,比如將所有的需要更改功能的類都繼承一個(gè)父類,在子類中調(diào)用父類的方法昼丑,這樣就少寫很多代碼呻逆。然而,這樣的機(jī)制仍然不是最方便的菩帝,如果父類中的方法發(fā)生改變咖城,那么調(diào)用父類方法的所有子類都要修改。

1.AOP的原理

aop采用的是橫向抽取機(jī)制呼奢,其底層使用動(dòng)態(tài)代理方式實(shí)現(xiàn)宜雀。在采用動(dòng)態(tài)代理方式時(shí),針對有接口和沒有接口的情況握础,分別采用不同的方式實(shí)現(xiàn)辐董。

1.針對有接口的情況,使用的是jdk的動(dòng)態(tài)代理禀综。實(shí)現(xiàn)類在實(shí)現(xiàn)接口的中間简烘,創(chuàng)建接口實(shí)現(xiàn)類的代理對象,這個(gè)代理對象和實(shí)現(xiàn)類是平級的定枷,并不是一個(gè)真正的對象夸研,只是實(shí)現(xiàn)和接口實(shí)現(xiàn)類相同的功能。

2.針對沒有接口的情況依鸥,使用的是cglib的動(dòng)態(tài)代理,創(chuàng)建該類的子類代理對象悼沈,在子類中調(diào)用父類的方法完成增強(qiáng)贱迟。

2.AOP操作術(shù)語

class UserService{
    
    void add(User user){}
    
    void update(User user){}
    
    void delete(Integer userId){}
    
    User getUserById(Integer userId){}
}

Joinpoint(連接點(diǎn)):在一個(gè)類中那些可以被增強(qiáng)的方法,這些方法稱之為連接點(diǎn)絮供,比如UserService中的四個(gè)方法衣吠,都可以稱之為連接點(diǎn),

Pointcut(切入點(diǎn)):在一個(gè)類中可以有多個(gè)連接點(diǎn)壤靶,但是只有實(shí)際被增強(qiáng)的方法才稱之為切入點(diǎn)缚俏。如果只對UserService中的add()方法進(jìn)行增強(qiáng),那么這個(gè)類中只有一個(gè)切入點(diǎn)。

Advice(通知/增強(qiáng)):增強(qiáng)的邏輯忧换,比如說要給add()方法增加日志打印的功能恬惯,那么這個(gè)功能就稱之為通知/增強(qiáng)。有前置通知亚茬、后置通知酪耳、異常通知、最終通知刹缝、環(huán)繞通知碗暗。

Aspect(切面):把增強(qiáng)應(yīng)用到具體方法上面的過程。比如說給add()方法增加日志打印的這個(gè)過程梢夯,就是切面言疗。

3.Spring中的aop操作@Aspectj(基于xml)

//被增強(qiáng)的類
public class BookService {

    public void add() {
        System.out.println("BookService.add()");
    }
}
public class BookServiceAdvice {

    //前置通知
    public void before() {
        System.out.println("before advice");
    }

    //后置通知
    public void after() {
        System.out.println("after advice");
    }

    //環(huán)繞通知
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //在方法之前執(zhí)行的方法
        System.out.println("before method advice");

        proceedingJoinPoint.proceed();

        //在方法之后執(zhí)行的方法
        System.out.println("after method advice");
    }
}

1.導(dǎo)入jar包

  • aopallinace-1.0.jar
  • aspectjweaver-1.8.7.jar
  • spring-aop-4.2.4.RELEASE.jar
  • spring-aspects-4.2.4.RELEASE.jar
    或者添加pom依賴:
<dependency>
  <groupId>org.springframework</groupId>
  <artifactId>spring-aspects</artifactId>
  <version>4.2.4.RELEASE</version>
</dependency>

2.在Spring配置文件中導(dǎo)入約束

http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd

3.幾種常見的常用的表達(dá)式

execution(<訪問修飾符>?<返回類型><方法名>(<參數(shù)>)<異常>)

  • execution(* com.aop.BookService.add(..)) ?*表示匹配所有的方法修飾符,..表示參數(shù)

  • execution(* com.aop.BookService.*(..)) ?第一個(gè)*表示匹配所有的方法修飾符,第二個(gè)*表示匹配該類下的所有方法

  • execution(* *.*(..))?表示對所有的方法進(jìn)行增強(qiáng)

  • execution(* add*(..))?表示對所有的以add開頭的方法進(jìn)行增強(qiáng)

4.配置對象(基于xml)

<bean id="bookService" class="com.aop.BookService"></bean>
<bean id="bookServiceAdvice" class="com.aop.BookServiceAdvice"></bean>

5.配置aop操作

<aop:config>
    <!--配置切入點(diǎn)-->
    <aop:pointcut expression="execution(* com.aop.BookService.add(..))" id="bookService_add_pointcut"/>
    <!--配置切面-->
    <aop:aspect ref="bookServiceAdvice">
        <!--配置增強(qiáng)類型-->
        <!--前置通知-->
        <aop:before method="before" pointcut-ref="bookService_add_pointcut"/>
        <!--后置通知-->
        <aop:after-returning method="after" pointcut-ref="bookService_add_pointcut"/>
        <!--環(huán)繞通知-->
        <aop:around method="around" pointcut-ref="bookService_add_pointcut"/>
    </aop:aspect>
</aop:config>

6.測試

ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
BookService bookService = (BookService) context.getBean("bookService");
bookService.add();

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

before advice
before method advice
BookService.add()
after method advice
after advice

4.Spring中的aop操作@Aspectj(基于注解)

在類上面加注解,導(dǎo)入jar包或者添加依賴颂砸,在配置文件中導(dǎo)入約束

@Service("bookService")
public class BookService {...}
@Service("bookServiceAdvice")
public class BookServiceAdvice {...}

1.在配置文件中開啟aop操作

<aop:aspectj-autoproxy></aop:aspectj-autoproxy>

2.在增強(qiáng)類上面添加注解

@Service("bookServiceAdvice")
@Aspect
public class BookServiceAdvice {

    //前置通知
    @Before(value = "execution(* com.aop.BookService.add(..))")
    public void before() {
        System.out.println("before advice");
    }

    //后置通知
    @After(value = "execution(* com.aop.BookService.add(..))")
    public void after() {
        System.out.println("after advice");
    }

    //環(huán)繞通知
    @Around(value = "execution(* com.aop.BookService.add(..))")
    public void around(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {
        //在方法之前執(zhí)行的方法
        System.out.println("before method advice");

        proceedingJoinPoint.proceed();

        //在方法之后執(zhí)行的方法
        System.out.println("after method advice");
    }
}
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末噪奄,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子沾凄,更是在濱河造成了極大的恐慌梗醇,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撒蟀,死亡現(xiàn)場離奇詭異叙谨,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)保屯,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門手负,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人姑尺,你說我怎么就攤上這事竟终。” “怎么了切蟋?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵统捶,是天一觀的道長。 經(jīng)常有香客問我柄粹,道長喘鸟,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任驻右,我火速辦了婚禮什黑,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘堪夭。我一直安慰自己愕把,他們只是感情好拣凹,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著恨豁,像睡著了一般嚣镜。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上圣絮,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天祈惶,我揣著相機(jī)與錄音,去河邊找鬼扮匠。 笑死捧请,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的棒搜。 我是一名探鬼主播疹蛉,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼力麸!你這毒婦竟也來了可款?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤克蚂,失蹤者是張志新(化名)和其女友劉穎闺鲸,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體埃叭,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡摸恍,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了赤屋。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片立镶。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖类早,靈堂內(nèi)的尸體忽然破棺而出媚媒,到底是詐尸還是另有隱情,我是刑警寧澤涩僻,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布缭召,位于F島的核電站,受9級特大地震影響逆日,放射性物質(zhì)發(fā)生泄漏恼琼。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一屏富、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧蛙卤,春花似錦狠半、人聲如沸噩死。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽已维。三九已至,卻和暖如春已日,著一層夾襖步出監(jiān)牢的瞬間垛耳,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工飘千, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留堂鲜,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓护奈,卻偏偏與公主長得像缔莲,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子霉旗,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

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