spring 中的AOP

大家好,我是IT修真院上海分院第02期學(xué)員,一枚正直善良的java程序員。
今天給分享一下修真院java任務(wù)一中關(guān)于spring AOP的相關(guān)知識(shí)。
1.背景介紹
在軟件開發(fā)中,散布于應(yīng)用中多處的功能被稱為橫切關(guān)注點(diǎn),這些橫切關(guān)注點(diǎn)從概念上是與應(yīng)用的業(yè)務(wù)邏輯相分離的,但往往會(huì)直接嵌入到應(yīng)用的業(yè)務(wù)邏輯中,把這些橫切關(guān)注點(diǎn)與業(yè)務(wù)邏輯相分離正是面向切面編程(AOP)所要解決的問(wèn)題

2.知識(shí)剖析
AOP中有幾個(gè)術(shù)語(yǔ)
橫切關(guān)注點(diǎn):系統(tǒng)中的非核心業(yè)務(wù)的功能,如日志等,橫切關(guān)注點(diǎn)可以被模塊化為特殊的類,這些類被稱為切面
通知:切面的工作被稱為通知,定義了切面是什么以及何時(shí)使用,spring切面有5種類型的通知
1.前置通知
2.后置通知
3.返回通知
4.異常通知
5.環(huán)繞通知
連接點(diǎn):連接點(diǎn)是程序執(zhí)行過(guò)程種能夠應(yīng)用通知的所有的點(diǎn)
切點(diǎn):切點(diǎn)定義了通知被應(yīng)用的具體位置(在哪些連接點(diǎn))
切面:切面和切點(diǎn)的結(jié)合,通知和切點(diǎn)共同定義了切面的全部?jī)?nèi)容,是什么,在何時(shí),在何處
引入:利用引入可以向現(xiàn)有的類添加新的方法或?qū)傩?br> 織入:把切面應(yīng)用到目標(biāo)對(duì)象并創(chuàng)建新的代理對(duì)象的過(guò)程

spring 提供了4種類型的AOP支持
1.基于代理的經(jīng)典spring AOP
2.純POJO切面
3.@AspectJ注解驅(qū)動(dòng)的切面
4.注入式AspectJ切面
前三種都是spring AOP實(shí)現(xiàn)的變體,構(gòu)建在動(dòng)態(tài)代理的基礎(chǔ)上
spring基于動(dòng)態(tài)代理,所以spring方法連接點(diǎn),相比于AspectJ,無(wú)法提供字段和構(gòu)造器接入點(diǎn),當(dāng)需要細(xì)粒度的控制切面時(shí),可以利用AspectJ來(lái)補(bǔ)充

3.常見(jiàn)問(wèn)題
在軟件開發(fā)中,散布于應(yīng)用中多處的行為,如日志,性能統(tǒng)計(jì)等,不應(yīng)該是應(yīng)用對(duì)象主動(dòng)參與的,應(yīng)用對(duì)象應(yīng)該只關(guān)注于自己所針對(duì)的業(yè)務(wù)問(wèn)題,而將與核心業(yè)務(wù)無(wú)關(guān)的行為交給其他對(duì)象來(lái)處理

4.解決方案
采用AOP,面向?qū)ο缶幊?,?shí)現(xiàn)輔助功能與核心業(yè)務(wù)的分離

5.編碼實(shí)戰(zhàn)
純POJO切面
目標(biāo)類:

public class Hehe {
public void hello(){
System.out.println("this is aop xml");
   }
}

定義將要作為切面的類:

public class Cut {
public void before(){
System.out.println("this is before");
   }
}

在xml中定義切面:

<bean id="hehe" class="aopxml.Hehe"/>
<bean id="cut" class="aopxml.Cut"/>
<aop:config>
   <aop:aspect ref="cut">
      <aop:pointcut id="hello" expression="execution(* aopxml.Hehe.hello(..))"/>
       <aop:before pointcut-ref="hello"
           method="before"/>
   </aop:aspect>
</aop:config>

先將兩個(gè)類聲明為bean,然后用命名空間<aop:config>定義切面,<aop:aspect ref="cut">引用作為切面的類,
<aop:pointcut id="hello" expression="execution(* aopxml.Hehe.hello(..))"/>定義了切點(diǎn),<aop:before pointcut-ref="hello" method="before"/>定義了通知類型為前置通知并應(yīng)用方法“before”

@AspectJ注解驅(qū)動(dòng)的切面
需要編寫一個(gè)配置類,用于開啟掃描:

@Configuration
@ComponentScan
@EnableAspectJAutoProxy
public class config {
}
目標(biāo)類:
public class Haha {
public void hello(){
System.out.println("this is aop ");
   }
}

定義切面:

@Component
@Aspect
public class Cut {
@Pointcut("execution(* aop.Haha.print(..))")
   public void cut(){
   }
   @Before("cut()")
   public void before(){
       System.out.println("this is before");
   }
}

@Aspect注解定義此類為bean,@Pointcut注解定義了一個(gè)切點(diǎn),如果其他通知要用相同的切點(diǎn),可以直接引用此注解下的方法,@Before("cut()")注解定義通知為前置通知,并引用前面的切點(diǎn)

6.擴(kuò)展思考
利用被稱為引入的AOP概念,切面可以為spring bean添加新的方法
先定義一個(gè)接口,以及接口的實(shí)現(xiàn)類:

public interface Hello {
void hello();
}
public class HelloImpl implements Hello{
public void hello(){
System.out.println("Hello JCY");
   }
}

在切面類中添加:

@DeclareParents(value = "aop.Haha+",defaultImpl = HelloImpl.class)
public Hello hello;

value = "aop.Haha+"表示為Haha類及其子類添加方法或?qū)傩?,其具體的實(shí)現(xiàn)由defaultImpl = HelloImpl.class定義,表示添加的是HelloImpl類中的方法和屬性,public Hello hello 聲明接口類型

7.參考文獻(xiàn)
spring 實(shí)戰(zhàn)

8.更多討論
問(wèn)題:
簡(jiǎn)單說(shuō)一下這幾種aop切面方法各有什么優(yōu)缺點(diǎn)
答:spring的經(jīng)典AOP比較笨重和復(fù)雜,已經(jīng)很少用到了。
利用XML配置,用spring的aop命名空間,可以將POJO轉(zhuǎn)換為切面,實(shí)現(xiàn)了 無(wú)侵入式編程
第三種,spring借鑒了AspectJ的編程模型,實(shí)現(xiàn)了不使用XML來(lái)實(shí)現(xiàn)定義切面,但是需要在源碼上進(jìn)行注解

那個(gè)aop除了我們打日志。還有什么常見(jiàn)應(yīng)用嗎?
答:性能統(tǒng)計(jì),事務(wù)管理等

結(jié)合log4j打印響應(yīng)時(shí)間,需要配置什么?
答:選定切點(diǎn),設(shè)置環(huán)繞通知,在目標(biāo)方法執(zhí)行前和執(zhí)行后分別獲取當(dāng)前時(shí)間,然后相減,并用log4j打印輸出

如何使用AOP代理靜態(tài)方法?
答:可以寫一個(gè)非靜態(tài)方法,然后里面調(diào)用靜態(tài)方法,再給這個(gè)非靜態(tài)方法加AOP

aop 是如何實(shí)現(xiàn)的呢...
答:通過(guò)代理來(lái)實(shí)現(xiàn)新增方法的執(zhí)行

視頻:https://v.qq.com/x/page/j0516last8h.html
PPT:https://ptteng.github.io/PPT/PPT-java/java-task1-spring-AOP.html#/

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

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