久久久精品一区ed2k-女人被男人叉到高潮的视频-中文字幕乱码一区久久麻豆樱花-俄罗斯熟妇真实视频

@Aspect怎么在SpringAOP中使用

本篇文章為大家展示了@Aspect怎么在Spring AOP中使用,內(nèi)容簡(jiǎn)明扼要并且容易理解,絕對(duì)能使你眼前一亮,通過這篇文章的詳細(xì)介紹希望你能有所收獲。

創(chuàng)新互聯(lián)是一家專業(yè)提供安義企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站建設(shè)、做網(wǎng)站、H5頁面制作、小程序制作等業(yè)務(wù)。10年已為安義眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站建設(shè)公司優(yōu)惠進(jìn)行中。

1 切點(diǎn)復(fù)合運(yùn)算

支持在切點(diǎn)定義中加入以下運(yùn)算符進(jìn)行復(fù)合運(yùn)算:

運(yùn)算符說明
&&與運(yùn)算。
!非運(yùn)算。
||或運(yùn)算。

2 切點(diǎn)命名

一般情況下,切點(diǎn)是直接聲明在需要增強(qiáng)方法處,這種切點(diǎn)的聲明方式稱為匿名切點(diǎn),匿名切點(diǎn)只能在聲明處被使用 。 如果希望在其它地方可以重用這個(gè)切點(diǎn),我們可以通過 @Pointcut 注解及切面類方法來命名它。

public class NamePointcut {

 /**
 * 切點(diǎn)被命名為 method1,且該切點(diǎn)只能在本類中使用
 */
 @Pointcut("within(net.deniro.spring4.aspectj.*)")
 private void method1() {
 }

 /**
 * 切點(diǎn)被命名為 method2,且該切點(diǎn)可以在本類或子孫類中使用
 */
 @Pointcut("within(net.deniro.spring4.aspectj.*)")
 protected void method2() {
 }

 /**
 * 切點(diǎn)被命名為 method3,且該切點(diǎn)可以在任何類中使用
 * 這里還使用了復(fù)合運(yùn)算
 */
 @Pointcut("method1() && method2()")
 public void method3() {
 }
}

命名切點(diǎn)的結(jié)構(gòu)如下:

@Aspect怎么在Spring AOP中使用

切點(diǎn)可訪問性修飾符與類可訪問性修飾符的功能是相同的,它可以決定定義的切點(diǎn)可以在哪些類中可使用。

因?yàn)槊悬c(diǎn)僅利用方法名及訪問修飾符的信息,所以我們一般定義方法的返回類型為 void ,并且方法體為空 。

定義好切點(diǎn)后,就可以在切面類中引用啦:

@Aspect
public class NamePointcutAspect {

 @After("NamePointcut.method2()")
 public void aspectMethod1() {
 }

 /**
 * 這里使用了復(fù)合運(yùn)算
 */
 @After("NamePointcut.method2() && NamePointcut.method3()")
 public void aspectMethod2() {
 }
}

3 織入順序

一個(gè)連接點(diǎn)可以同時(shí)匹配多個(gè)切點(diǎn),而切點(diǎn)所對(duì)應(yīng)的增強(qiáng)在連接點(diǎn)上織入順序的規(guī)則是這樣的:

1.如果在同一個(gè)切面類中聲明的增強(qiáng),則按照增強(qiáng)在切面類中定義的順序進(jìn)行織入;

2.如果增強(qiáng)位于不同的切面類中,并且這些切面類都實(shí)現(xiàn)了org.springframework.core.Ordered 接口,則由 Ordered 方法的順序號(hào)決定(順序號(hào)小的先織入);

3.如果增強(qiáng)位于不同的切面類中,但這些切面類沒有實(shí)現(xiàn)org.springframework.core.Ordered 接口,織入的順序是不確定的 。

假設(shè)有兩個(gè)切面類 A 與 B,它們都實(shí)現(xiàn)了 Ordered 接口,A 的順序號(hào)為 1,B 的順序號(hào)為 2,切面類 A 與 B 都定義了 3 個(gè)增強(qiáng),那么同時(shí)匹配這 6 個(gè)增強(qiáng)的織入順序如下圖所示:

@Aspect怎么在Spring AOP中使用

4 獲取連接點(diǎn)信息

4.1 JoinPoint

org.aspectj.lang.JoinPoint 接口表示目標(biāo)類連接點(diǎn)對(duì)象,它定義這些主要方法。

方法說明
Object[] getArgs()獲取連接點(diǎn)方法運(yùn)行時(shí)的入?yún)⒘斜怼?/td>
Signature getSignature()獲取連接點(diǎn)的方法簽名對(duì)象。
Object getTarget()獲取連接點(diǎn)所在的目標(biāo)對(duì)象。
Object getThis()獲取代理對(duì)象。

4.2 ProceedingJoinPoint

org.aspectj.lang.ProceedingJoinPoint 繼承了 JoinPoint 接口,它新增了兩個(gè)方法(它們用于執(zhí)行連接點(diǎn)方法)。

方法說明
Object proceed() throws Throwable通過反射執(zhí)行目標(biāo)對(duì)象連接點(diǎn)處的方法。
Object proceed(Object[] var1) throws Throwable使用新的入?yún)ⅲㄌ鎿Q掉原來的入?yún)ⅲ?,通過反射執(zhí)行目標(biāo)對(duì)象連接點(diǎn)處的方法。

4.3 示例

Cook 接口:

public interface Cook {

 /**
 * 制作食品
 */
 void make();

 /**
 * 制作
 *
 * @param name 食品名稱
 */
 void make(String name);
}

CookA 類:

public class CookA implements Cook {
 public void make() {
 System.out.println("制作食品");
 }

 public void make(String name) {
 System.out.println("制作" + name);
 }
}

在切面類中訪問連接點(diǎn)信息:

@Aspect
public class JoinPointAspect {

 @Around("within(net.deniro.spring4.aspectj.CookA)")
 public void test(ProceedingJoinPoint pjp) throws Throwable {
 System.out.println("---------獲取連接點(diǎn)對(duì)象【開始】---------");
 System.out.println("參數(shù):" + pjp.getArgs()[0]);
 System.out.println("簽名對(duì)象:" + pjp.getTarget().getClass());

 //執(zhí)行目標(biāo)對(duì)象方法
 pjp.proceed();
 System.out.println("---------獲取連接點(diǎn)對(duì)象【結(jié)束】---------");

 }
}

Spring bean 配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
 xmlns:aop="http://www.springframework.org/schema/aop"
 xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd">

 <!--aspectj 驅(qū)動(dòng)器 -->
 <aop:aspectj-autoproxy/>

 <bean id="cookA" class="net.deniro.spring4.aspectj.CookA"/>
 <bean class="net.deniro.spring4.aspectj.JoinPointAspect"/>
</beans>

輸出結(jié)果:

---------獲取連接點(diǎn)對(duì)象【開始】---------
參數(shù):壽司
簽名對(duì)象:class net.deniro.spring4.aspectj.CookA
制作壽司
---------獲取連接點(diǎn)對(duì)象【結(jié)束】---------

5 綁定連接點(diǎn)的方法入?yún)?/strong>

args()、this()、target()、@args()、@within()、@target() 和 @annotation() 這些切點(diǎn)函數(shù)除可以指定類名外,還可以指定參數(shù)名,將目標(biāo)對(duì)象連接點(diǎn)上的方法入?yún)⒔壎ǖ皆鰪?qiáng)的方法中 。 其中 args() 用于綁定連接點(diǎn)方法的入?yún)ⅲ?@annotation() 用于綁定連接點(diǎn)方法的注解對(duì)象,而 @args() 用于綁定連接點(diǎn)方法入?yún)⒌淖⒔狻?/p>

CookC 類:

public class CookC implements Cook {
 public void make() {
 System.out.println("制作食品");
 }

 public void make(String name) {
 System.out.println("制作" + name);
 }

 public void make(String name, int num) {
 System.out.println("制作" + name + " " + num + " 個(gè)");
 }
}

切面類:

@Aspect
public class ParamsAspect {

 @Before("target(net.deniro.spring4.aspectj.CookC) && args(name,num,..)")
 public void test(String name,int num) {
 System.out.println("----------綁定連接點(diǎn)入?yún)ⅰ鹃_始】----------");
 System.out.println("name:" + name);
 System.out.println("num:" + num);
 System.out.println("----------綁定連接點(diǎn)入?yún)ⅰ窘Y(jié)束】----------");

 }
}
  • 這里的連接點(diǎn)表達(dá)式 args(name,num,..) 會(huì)先找到 name 與 num 的類型,從而生成真正的表達(dá)式 args(String,int,..)。

  • 增強(qiáng)方法可以通過 name 與 num 得到連接點(diǎn)的方法入?yún)ⅰ?/p>

切點(diǎn)匹配和參數(shù)綁定的過程是這樣的:

  1. args()會(huì)根據(jù)參數(shù)名稱在增強(qiáng)方法中查到名稱相同的入?yún)⒉@得對(duì)應(yīng)參數(shù)的類型,這樣就得到了匹配連接點(diǎn)方法的入?yún)㈩愋?。

  2. 連接點(diǎn)方法入?yún)㈩愋退诘奈恢糜蓞?shù)名在 args() 函數(shù)中聲明的位置決定 。

上述示例中的匹配過程如下:

@Aspect怎么在Spring AOP中使用

Spring 配置:

<!--aspectj 驅(qū)動(dòng)器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>

<bean id="cookC" class="net.deniro.spring4.aspectj.CookC"/>
<bean class="net.deniro.spring4.aspectj.ParamsAspect"/>

注意:這里必須通過 <aop:aspectj-autoproxy proxy-target-class="true" />來啟用 CGLib 動(dòng)態(tài)代理,這是因?yàn)?CookC 的 public void make(String name, int num) 是該類獨(dú)有的方法(非接口定義的方法),所以必須使用 CGLib 生成子類的代理方法 。

單元測(cè)試:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
CookC cookC = (CookC) context.getBean("cookC");
cookC.make("壽司", 100);

輸出結(jié)果:

----------綁定連接點(diǎn)入?yún)ⅰ鹃_始】----------
name:壽司
num:100
----------綁定連接點(diǎn)入?yún)ⅰ窘Y(jié)束】----------
制作壽司 100 個(gè)

6 綁定代理對(duì)象

使用 this() 或 target() 可綁定被代理對(duì)象的實(shí)例。通過類實(shí)例名綁定對(duì)象時(shí),依然具有原來連接點(diǎn)匹配的功能,只是類名是由增強(qiáng)方法中的同名入?yún)㈩愋烷g接決定的。

@Aspect
public class ProxyAspect {

 @Before("this(cook)")
 public void bind(Cook cook) {
  System.out.println("--------綁定代理對(duì)象【開始】--------");
  System.out.println(cook.getClass().getName());
  System.out.println("--------綁定代理對(duì)象【結(jié)束】--------");
 }
}

首先通過 public void bind(Cook cook) 找出 cook 所對(duì)應(yīng)的類型,接著轉(zhuǎn)換切點(diǎn)表達(dá)式為 this(net.deniro.spring4.aspectj.Cook) 。這樣就表示該切點(diǎn)匹配所有代理對(duì)象為 Cook 類中的所有方法。

輸出結(jié)果:

--------綁定代理對(duì)象【開始】--------
net.deniro.spring4.aspectj.CookC$$EnhancerBySpringCGLIB$$217fb793
--------綁定代理對(duì)象【結(jié)束】--------

target() 綁定與 this() 相似。

7 綁定類注解對(duì)象

@within() 和 @target() 函數(shù)都可以將目標(biāo)類的注解對(duì)象綁定到增強(qiáng)方法中。

定義一個(gè)日志注解類:

@Retention(RetentionPolicy.RUNTIME)//保留期限
@Target({ElementType.METHOD,ElementType.TYPE})//目標(biāo)類型
public @interface Log {
 boolean value() default true;//聲明成員變量
}

把該注解類應(yīng)用于 CookD:

@Log
public class CookD implements Cook {
 public void make() {
  System.out.println("制作糕點(diǎn)");
 }

 public void make(String name) {

 }
}

綁定類注解對(duì)象:

@Aspect
public class ClassAnnotationObjectAspect {

 @Before("@within(log)")
 public void bind(Log log){
  System.out.println("----------綁定類注解對(duì)象【開始】----------");
  System.out.println(log.getClass().getName());
  System.out.println("----------綁定類注解對(duì)象【結(jié)束】----------");
 }
}

Spring 配置:

<!--aspectj 驅(qū)動(dòng)器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>


<bean id="cookD" class="net.deniro.spring4.aspectj.CookD"/>
<bean class="net.deniro.spring4.aspectj.ClassAnnotationObjectAspect"/>

單元測(cè)試:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
CookD cook = (CookD) context.getBean("cookD");
cook.make();

輸出結(jié)果:

----------綁定類注解對(duì)象【開始】----------
com.sun.proxy.$Proxy8
----------綁定類注解對(duì)象【結(jié)束】----------

從輸出結(jié)果  com.sun.proxy.$Proxy8 可以看出 ,CookD 類的注解 Log 對(duì)象也被代理咯O(∩_∩)O哈哈~

8 綁定返回值

在后置增強(qiáng)中,可以通過 returning 來綁定連接點(diǎn)方法的返回值。

切面:

@Aspect
public class ReturnValueAspect {

 @AfterReturning(value = "target(net.deniro.spring4.aspectj.CookA)", returning = "value")
 public void bind(boolean value) {
  System.out.println("綁定返回值【開始】");
  System.out.println("value:" + value);
  System.out.println("綁定返回值【結(jié)束】");
 }
}

注意:returning 的值必須與方法參數(shù)名相同。

CookA 新增 smell 方法:

public boolean smell(String name) {
 System.out.println(name + "香嗎?");
 return true;
}

單元測(cè)試:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
CookA cook = (CookA) context.getBean("cookA");
cook.smell("烤鴨");

輸出結(jié)果:

烤鴨香嗎?
綁定返回值【開始】
value:true
綁定返回值【結(jié)束】

9 綁定異常

可以使用 AfterThrowing 注解的 throwing 成員變量來綁定連接點(diǎn)拋出的異常。

切面類:

@Aspect
public class ExceptionAspect {

 @AfterThrowing(value = "target(net.deniro.spring4.aspectj.CookA)",throwing = "e")
 public void bind(CookException e){
  System.out.println("綁定異?!鹃_始】");
  System.out.println("e:" + e.getMessage());
  System.out.println("綁定異?!窘Y(jié)束】");
 }
}

注意:throwing 的值必須與方法參數(shù)名相同。

單元測(cè)試:

ApplicationContext context = new ClassPathXmlApplicationContext("spring-beans.xml");
CookA cook = (CookA) context.getBean("cookA");
cook.make("");

輸出結(jié)果:

綁定異常【開始】
e:煮啥呢???
綁定異常【結(jié)束】

上述內(nèi)容就是@Aspect怎么在Spring AOP中使用,你們學(xué)到知識(shí)或技能了嗎?如果還想學(xué)到更多技能或者豐富自己的知識(shí)儲(chǔ)備,歡迎關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道。

新聞標(biāo)題:@Aspect怎么在SpringAOP中使用
鏈接地址:http://sd-ha.com/article14/jicpge.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、網(wǎng)站維護(hù)、標(biāo)簽優(yōu)化、ChatGPT、關(guān)鍵詞優(yōu)化Google

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)