国产片侵犯亲女视频播放_亚洲精品二区_在线免费国产视频_欧美精品一区二区三区在线_少妇久久久_在线观看av不卡

服務(wù)器之家:專注于服務(wù)器技術(shù)及軟件下載分享
分類導(dǎo)航

PHP教程|ASP.NET教程|Java教程|ASP教程|編程技術(shù)|正則表達式|C/C++|IOS|C#|Swift|Android|VB|R語言|JavaScript|易語言|vb.net|

服務(wù)器之家 - 編程語言 - Java教程 - 談?wù)凷pring AOP中@Aspect的高級用法示例

談?wù)凷pring AOP中@Aspect的高級用法示例

2021-05-26 13:35deniro Java教程

在Spring AOP中目前只有執(zhí)行方法這一個連接點,下面這篇文章主要給大家介紹了關(guān)于Spring AOP中@Aspect的高級用法的相關(guān)資料,文中通過示例代碼介紹的非常詳細,需要的朋友可以參考借鑒,下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧

前言

本文主要跟大家分享介紹了關(guān)于spring aop中@aspect的高級用法,下面話不多說了,來隨著小編一起看看詳細的介紹吧。

1 切點復(fù)合運算

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

 

運算符 說明
&& 與運算。
! 非運算。
|| 或運算。

 

2 切點命名

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

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public class namepointcut {
 
 /**
 * 切點被命名為 method1,且該切點只能在本類中使用
 */
 @pointcut("within(net.deniro.spring4.aspectj.*)")
 private void method1() {
 }
 
 /**
 * 切點被命名為 method2,且該切點可以在本類或子孫類中使用
 */
 @pointcut("within(net.deniro.spring4.aspectj.*)")
 protected void method2() {
 }
 
 /**
 * 切點被命名為 method3,且該切點可以在任何類中使用
 * 這里還使用了復(fù)合運算
 */
 @pointcut("method1() && method2()")
 public void method3() {
 }
}

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

談?wù)凷pring AOP中@Aspect的高級用法示例

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

因為命名切點僅利用方法名及訪問修飾符的信息,所以我們一般定義方法的返回類型為 void ,并且方法體為空 。

定義好切點后,就可以在切面類中引用啦:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
@aspect
public class namepointcutaspect {
 
 @after("namepointcut.method2()")
 public void aspectmethod1() {
 }
 
 /**
 * 這里使用了復(fù)合運算
 */
 @after("namepointcut.method2() && namepointcut.method3()")
 public void aspectmethod2() {
 }
}

3 織入順序

一個連接點可以同時匹配多個切點,而切點所對應(yīng)的增強在連接點上織入順序的規(guī)則是這樣的:

1.如果在同一個切面類中聲明的增強,則按照增強在切面類中定義的順序進行織入;

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

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

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

談?wù)凷pring AOP中@Aspect的高級用法示例

4 獲取連接點信息

4.1 joinpoint

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

 

方法 說明
object[] getargs() 獲取連接點方法運行時的入?yún)⒘斜怼?/td>
signature getsignature() 獲取連接點的方法簽名對象。
object gettarget() 獲取連接點所在的目標(biāo)對象。
object getthis() 獲取代理對象。

 

4.2 proceedingjoinpoint

org.aspectj.lang.proceedingjoinpoint 繼承了 joinpoint 接口,它新增了兩個方法(它們用于執(zhí)行連接點方法)。

方法 說明
object proceed() throws throwable 通過反射執(zhí)行目標(biāo)對象連接點處的方法。
object proceed(object[] var1) throws throwable 使用新的入?yún)ⅲㄌ鎿Q掉原來的入?yún)ⅲㄟ^反射執(zhí)行目標(biāo)對象連接點處的方法。

4.3 示例

cook 接口:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public interface cook {
 
 /**
 * 制作食品
 */
 void make();
 
 /**
 * 制作
 *
 * @param name 食品名稱
 */
 void make(string name);
}

cooka 類:

?
1
2
3
4
5
6
7
8
9
public class cooka implements cook {
 public void make() {
 system.out.println("制作食品");
 }
 
 public void make(string name) {
 system.out.println("制作" + name);
 }
}

在切面類中訪問連接點信息:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
@aspect
public class joinpointaspect {
 
 @around("within(net.deniro.spring4.aspectj.cooka)")
 public void test(proceedingjoinpoint pjp) throws throwable {
 system.out.println("---------獲取連接點對象【開始】---------");
 system.out.println("參數(shù):" + pjp.getargs()[0]);
 system.out.println("簽名對象:" + pjp.gettarget().getclass());
 
 //執(zhí)行目標(biāo)對象方法
 pjp.proceed();
 system.out.println("---------獲取連接點對象【結(jié)束】---------");
 
 }
}

spring bean 配置:

?
1
2
3
4
5
6
7
8
9
10
11
12
<?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ū)動器 -->
 <aop:aspectj-autoproxy/>
 
 <bean id="cooka" class="net.deniro.spring4.aspectj.cooka"/>
 <bean class="net.deniro.spring4.aspectj.joinpointaspect"/>
</beans>

輸出結(jié)果:

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

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

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

cookc 類:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
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 + " 個");
 }
}

切面類:

?
1
2
3
4
5
6
7
8
9
10
11
12
@aspect
public class paramsaspect {
 
 @before("target(net.deniro.spring4.aspectj.cookc) && args(name,num,..)")
 public void test(string name,int num) {
 system.out.println("----------綁定連接點入?yún)ⅰ鹃_始】----------");
 system.out.println("name:" + name);
 system.out.println("num:" + num);
 system.out.println("----------綁定連接點入?yún)ⅰ窘Y(jié)束】----------");
 
 }
}
  • 這里的連接點表達式 args(name,num,..) 會先找到 name 與 num 的類型,從而生成真正的表達式 args(string,int,..)。
  • 增強方法可以通過 name 與 num 得到連接點的方法入?yún)ⅰ?/li>

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

  1. args()會根據(jù)參數(shù)名稱在增強方法中查到名稱相同的入?yún)⒉@得對應(yīng)參數(shù)的類型,這樣就得到了匹配連接點方法的入?yún)㈩愋?。
  2. 連接點方法入?yún)㈩愋退诘奈恢糜蓞?shù)名在 args() 函數(shù)中聲明的位置決定 。

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

談?wù)凷pring AOP中@Aspect的高級用法示例

spring 配置:

?
1
2
3
4
5
<!--aspectj 驅(qū)動器 -->
<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 動態(tài)代理,這是因為 cookc 的 public void make(string name, int num) 是該類獨有的方法(非接口定義的方法),所以必須使用 cglib 生成子類的代理方法 。

單元測試:

?
1
2
3
applicationcontext context = new classpathxmlapplicationcontext("spring-beans.xml");
cookc cookc = (cookc) context.getbean("cookc");
cookc.make("壽司", 100);

輸出結(jié)果:

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

6 綁定代理對象

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

?
1
2
3
4
5
6
7
8
9
10
@aspect
public class proxyaspect {
 
 @before("this(cook)")
 public void bind(cook cook) {
  system.out.println("--------綁定代理對象【開始】--------");
  system.out.println(cook.getclass().getname());
  system.out.println("--------綁定代理對象【結(jié)束】--------");
 }
}

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

輸出結(jié)果:

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

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

7 綁定類注解對象

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

定義一個日志注解類:

?
1
2
3
4
5
@retention(retentionpolicy.runtime)//保留期限
@target({elementtype.method,elementtype.type})//目標(biāo)類型
public @interface log {
 boolean value() default true;//聲明成員變量
}

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

?
1
2
3
4
5
6
7
8
9
10
@log
public class cookd implements cook {
 public void make() {
  system.out.println("制作糕點");
 }
 
 public void make(string name) {
 
 }
}

綁定類注解對象:

?
1
2
3
4
5
6
7
8
9
10
@aspect
public class classannotationobjectaspect {
 
 @before("@within(log)")
 public void bind(log log){
  system.out.println("----------綁定類注解對象【開始】----------");
  system.out.println(log.getclass().getname());
  system.out.println("----------綁定類注解對象【結(jié)束】----------");
 }
}

spring 配置:

?
1
2
3
4
5
6
<!--aspectj 驅(qū)動器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
 
 
<bean id="cookd" class="net.deniro.spring4.aspectj.cookd"/>
<bean class="net.deniro.spring4.aspectj.classannotationobjectaspect"/>

單元測試:

?
1
2
3
applicationcontext context = new classpathxmlapplicationcontext("spring-beans.xml");
cookd cook = (cookd) context.getbean("cookd");
cook.make();

輸出結(jié)果:

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

從輸出結(jié)果  com.sun.proxy.$proxy8 可以看出 ,cookd 類的注解 log 對象也被代理咯o(∩_∩)o哈哈~

8 綁定返回值

在后置增強中,可以通過 returning 來綁定連接點方法的返回值。

切面:

?
1
2
3
4
5
6
7
8
9
10
@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 方法:

?
1
2
3
4
public boolean smell(string name) {
 system.out.println(name + "香嗎?");
 return true;
}

單元測試:

?
1
2
3
applicationcontext context = new classpathxmlapplicationcontext("spring-beans.xml");
cooka cook = (cooka) context.getbean("cooka");
cook.smell("烤鴨");

輸出結(jié)果:

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

9 綁定異常

可以使用 afterthrowing 注解的 throwing 成員變量來綁定連接點拋出的異常。

切面類:

?
1
2
3
4
5
6
7
8
9
10
@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("綁定異常【結(jié)束】");
 }
}

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

單元測試:

?
1
2
3
applicationcontext context = new classpathxmlapplicationcontext("spring-beans.xml");
cooka cook = (cooka) context.getbean("cooka");
cook.make("");

輸出結(jié)果:

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

總結(jié)

以上就是這篇文章的全部內(nèi)容了,希望本文的內(nèi)容對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,如果有疑問大家可以留言交流,謝謝大家對服務(wù)器之家的支持。

原文鏈接:https://www.jianshu.com/p/0d7cf0aeb338

延伸 · 閱讀

精彩推薦
Weibo Article 1 Weibo Article 2 Weibo Article 3 Weibo Article 4 Weibo Article 5 Weibo Article 6 Weibo Article 7 Weibo Article 8 Weibo Article 9 Weibo Article 10 Weibo Article 11 Weibo Article 12 Weibo Article 13 Weibo Article 14 Weibo Article 15 Weibo Article 16 Weibo Article 17 Weibo Article 18 Weibo Article 19 Weibo Article 20 Weibo Article 21 Weibo Article 22 Weibo Article 23 Weibo Article 24 Weibo Article 25 Weibo Article 26 Weibo Article 27 Weibo Article 28 Weibo Article 29 Weibo Article 30 Weibo Article 31 Weibo Article 32 Weibo Article 33 Weibo Article 34 Weibo Article 35 Weibo Article 36 Weibo Article 37 Weibo Article 38 Weibo Article 39 Weibo Article 40
主站蜘蛛池模板: 激情欧美一区二区三区中文字幕 | 国产欧美精品一区二区三区 | 亚洲久久久久 | 久久亚洲一区二区 | 国产精品一级毛片在线 | 亚洲乱码二区 | 欧美资源在线 | 欧美日韩在线电影 | 日韩欧美国产一区二区三区 | 久久久亚洲精品视频 | 能看的av网站 | 亚洲 欧美 日韩 在线 | 三级黄色小视频 | 国产精品二区一区二区aⅴ污介绍 | 日韩欧美国产一区二区 | 国产欧美日韩一区二区三区 | 中文字幕亚洲一区二区三区 | 免费h | 欧美黄视频 | 91精品国产综合久久久久久丝袜 | 日韩视频精品 | 成人黄色小视频 | 成人精品网站在线观看 | 亚洲乱码国产乱码精品精的特点 | 国产一区二区在线免费观看 | 国产精品久久久久一区二区三区 | 成人精品电影 | 色网站在线视频 | 中文字幕免费看 | 亚洲在线一区二区 | 国产精品一区不卡 | 欧美日韩免费看 | 一区二区三区四区日韩 | 精品伦精品一区二区三区视频 | 亚洲精品乱码久久久久久花季 | 成人午夜电影网 | 一区二区三区精品视频 | 久久久久久亚洲精品中文字幕 | 欧美日韩精品一区 | 欧美日韩第一页 | 国产毛片v一区二区三区 |