Spring-AOP @AspectJ進階之命名切點
概述
在前面所舉的例子中,比如
@Before("within(com.xgj.aop.spring.advisor.aspectJAdvance.pointcutComplex.*)"
+ " && execution(* greetTo(..))")
public void matchGreetTo() {
System.out.println("matchGreetTo executed,some logic is here ");
}
切點直接宣告在增強方法處,這種切點宣告方式稱為匿名切點,匿名切點只能在宣告處使用。
如果希望在其它地方重用一個切點,我們可以通過@Pointcut註解以及切面類方法對切點進行命名
示例
package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;
import org.aspectj.lang.annotation.Pointcut;
/**
*
*
* @ClassName: NamePoint
*
* @Description: 如果希望在其它地方重用一個切點,我們可以通過@Pointcut註解以及切面類方法對切點進行命名
*
* @author: Mr.Yang
*
* @date : 2017年9月10日 下午11:13:45
*/
public class NamePoint{
/**
*
*
* @Title: inPackage
*
* @Description: 通過註解方法inPackage()對該切點進行命名,方法可視域
* 修飾符為private,表明該命名切點只能在本切面類中使用。
*
*
* @return: void
*/
@Pointcut("within(com.xgj.aop.spring.advisor.aspectJAdvance.namePoint)" )
private void inPackage() {
};
/**
*
*
* @Title: greetTo
*
* @Description: 通過註解方法greetTo()對該切點進行命名,方法可視域
* 修飾符為protected,表明該命名切點可以在當前包中的切面 類、子切面類中中使用。
*
*
* @return: void
*/
@Pointcut("execution(* greetTo(..))")
protected void greetTo() {
}
/**
*
*
* @Title: inPkgGreetTo
*
* @Description: 引用命名切點定義的切點,本切點也是命名切點, 它對應的可視域為public
*
*
* @return: void
*/
@Pointcut("inPackage() and greetTo()")
public void inPkgGreetTo() {
}
}
上面上述示例中定義了3個命名切點,命名切點的使用類方法作為切點的名稱,此外方法的訪問修飾符還控制了切點的可引用性,這種可引用性和類方法的可訪問性相同,如private的切點只能在本類中引用,public的切點可以在任何類中引用。
命名切點僅利用方法名及訪問修飾符的資訊,所以習慣上,方法的返回型別為void,並且方法體為空。
我們可以通過下圖更直觀地瞭解命名切點的結構:
inPkgGreetTo()的切點引用了同類中的greetTo()切點,而inPkgGreetTo()切點可以被任何類引用。
你還可以擴充套件NamePoint類,通過類的繼承關係定義更多的切點。 命名切點定義好後,就可以在定義切面時通過名稱引用切點.
來看個示例
假設有兩個業務類
package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;
import org.springframework.stereotype.Component;
/**
*
*
* @ClassName: NaiveWaiter
*
* @Description: @Component註解標註的bean
*
* @author: Mr.Yang
*
* @date: 2017年9月10日 下午11:55:00
*/
@Component
public class NaiveWaiter {
public void greetTo(String clientName) {
System.out.println("NaiveWaiter greetTo " + clientName);
}
public void serverTo(String clientName) {
System.out.println("NaiveWaiter serverTo " + clientName);
}
}
package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;
import org.springframework.stereotype.Component;
@Component
public class CuteWaiter {
public void greetTo(String clientName) {
System.out.println("CuteWaiter greetTo " + clientName);
}
public void serverTo(String clientName) {
System.out.println("CuteWaiter serverTo " + clientName);
}
}
切點命名複用上面那個切點,然後編寫切面NamePointAspect
package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;
import org.aspectj.lang.annotation.AfterReturning;
import org.aspectj.lang.annotation.Aspect;
/**
*
*
* @ClassName: NamePointTest
*
* @Description: 使用@Aspect註解標註的切面,演示命名切點的使用
*
* @author: Mr.Yang
*
* @date: 2017年9月10日 下午11:42:39
*/
@Aspect
public class NamePointAspect {
/**
*
*
* @Title: pkgGreetTo
*
* @Description: 引用了NamePoint.inPkgGreetTo()切點
*
*
* @return: void
*/
@AfterReturning("NamePoint.inPkgGreetTo()")
public void pkgGreetTo() {
System.out.println("pkgGreetTo exectued ,some logic is here ");
}
/**
*
*
* @Title: pkgGreetToNotNaiveWaiter
*
* @Description: 在複合運算中使用了命名切點
*
*
* @return: void
*/
@AfterReturning("!target(com.xgj.aop.spring.advisor.aspectJAdvance.namePoint.NaiveWaiter) && NamePoint.inPkgGreetTo()")
public void pkgGreetToNotNaiveWaiter() {
System.out
.println("pkgGreetToNotNaiveWaiter() executed,some logic is here");
}
}
配置檔案如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- (1)宣告Context名稱空間以及Schema檔案 (2)掃描類包以及應用註解定義的bean -->
<context:component-scan base-package="com.xgj.aop.spring.advisor.aspectJAdvance.namePoint"/>
<!-- 基於@AspectJ切面的驅動器 -->
<aop:aspectj-autoproxy proxy-target-class="true"/>
<!-- 使用了@AspectJ註解的切面類 -->
<bean class="com.xgj.aop.spring.advisor.aspectJAdvance.namePoint.NamePointAspect"/>
</beans>
測試類
package com.xgj.aop.spring.advisor.aspectJAdvance.namePoint;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
*
*
* @ClassName: NamePointAspectTest
*
* @Description: 命名切點測試類
*
* @author: Mr.Yang
*
* @date: 2017年9月10日 下午11:56:50
*/
public class NamePointAspectTest {
public static void main(String[] args) {
ApplicationContext ctx = new ClassPathXmlApplicationContext(
"classpath:com/xgj/aop/spring/advisor/aspectJAdvance/namePoint/conf-namePoint.xml");
CuteWaiter cuteWaiter = ctx.getBean("cuteWaiter", CuteWaiter.class);
NaiveWaiter naiveWaiter = ctx.getBean("naiveWaiter", NaiveWaiter.class);
naiveWaiter.greetTo("XiaoGongJiang");
System.out.println("================");
cuteWaiter.greetTo("XiaoGongJiang");
System.out.println("================");
naiveWaiter.serverTo("XiaoGongJiang");
System.out.println("================");
cuteWaiter.serverTo("XiaoGongJiang");
}
}
執行結果
2017-09-11 00:58:34,752 INFO [main] (AbstractApplicationContext.java:583) - Refreshing org[email protected]4888884e: startup date [Mon Sep 11 00:58:34 BOT 2017]; root of context hierarchy
2017-09-11 00:58:34,821 INFO [main] (XmlBeanDefinitionReader.java:317) - Loading XML bean definitions from class path resource [com/xgj/aop/spring/advisor/aspectJAdvance/namePoint/conf-namePoint.xml]
NaiveWaiter greetTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here
================
CuteWaiter greetTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here
pkgGreetToNotNaiveWaiter() executed,some logic is here
================
NaiveWaiter serverTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here
================
CuteWaiter serverTo XiaoGongJiang
pkgGreetTo exectued ,some logic is here
pkgGreetToNotNaiveWaiter() executed,some logic is here
可以看到NaiveWaiter greetTo 方法 沒有織入第二個增強。
相關推薦
Spring-AOP @AspectJ進階之命名切點
概述 示例 概述 在前面所舉的例子中,比如 @Before("within(com.xgj.aop.spring.advisor.aspectJAdvance.pointcutComplex.*)" + " &a
Spring-AOP @AspectJ進階之繫結類註解物件
概述 例項 概述 @within()和@target()函式可以將目標類的註解物件繫結到增強方法中。 我們通過@within()演示註解繫結的操作 例項 註
Spring-AOP @AspectJ進階之繫結丟擲的異常
概述 例項 總結 概述 和通過切點函式繫結連線點資訊不同,連線點丟擲的異常必須使用AfterThrowing註解的throwing成員進行繫結 例項 業務類 p
Spring-AOP @AspectJ進階之繫結連線點方法入參
概述 例項 概述 我們前面的博文在講解切點函式時說過args()、this()、target()、@args()、@within()、@target()和@annotation()這
Spring-AOP @AspectJ進階之增強織入的順序
概述 示例 概述 一個連線點可以同時匹配多個切點,切點對應的增強在連線點上的織入順序到底是如何安排呢?這個問題需要分三種情況討論: 如果增強在同一個切面類中宣告,則依照增強在切
spring ioc---DI進階之雜項(idref標籤;複合屬性;懶載入)
雜項 說明 idref標籤 注入的是容器中例項bean的id值,型別是java.lang.String,而非bean例項! attr1.attr2.attr3 採用巢狀屬性的方式,可直接設
spring ioc---DI進階之方法的注入和替換
方法注入解決的需求: 若bean A依賴bean B,在兩者生命週期不同的情況下,若bean A每次使用bean B的例項的時候,都需要擁有不同狀態的bean B的例項的話,就需要使用方法注入的功能,來實現此需求.(需要使用cglib技術)
spring ioc---DI進階之自動裝配
模式 說明 no/default (Default) No autowiring. Bean references must be defined via a ref element. Changing the default
spring ioc---DI進階之引入依賴關係不明顯的bean
1,需要在bean標籤中使用屬性`depends-on`. 簡言之,在使用bean之前,被標註的依賴bean要先於初始化.雖然兩個bean之間的依賴關係不是清晰明顯且直接的. 官方xsd中關於depends-on的說明 文件地址:http://www.springframework.
spring ioc---DI進階之引入其他bean
官方xsd文件中關於ref的參考說明 原文連結:http://www.springframework.org/schema/beans/spring-beans.xsd 1.標籤ref: Defines a reference to another bean in this fact
spring ioc---DI進階之集合和特殊值的處理
DI進階之集合的使用 集合 使用 list連結串列容器 使用list和value標籤 set無序容器 使用set和value標籤 map鍵值對
Spring入門(十一):Spring AOP使用進階
在上篇部落格中,我們瞭解了什麼是AOP以及在Spring中如何使用AOP,本篇部落格繼續深入講解下AOP的高階用法。 1. 宣告帶引數的切點 假設我們有一個介面CompactDisc和它的實現類BlankDisc: package chapter04.soundsystem; /** * 光碟 */ p
Spring 之AOP AspectJ切入點語法詳解 @AspectJ進階
AspectJ切入點語法詳解 此文章來源於網路,版權不歸本人所有。本人結合起來 1.Spring AOP @Before @Around @After 等 advice 的執行順序 @Around/**ProceedingJo
Spring-AOP @AspectJ切點函式之args()和@args()
概述 args args 例項 args args 概述 args函式的入參是類名, 而 @args()的入參必須是註解類的類名。 雖然args()允許在類名後使用“+”萬用字元,但該萬用字元在此處沒有意義,新增和不新增的效果都一樣。
Spring-AOP @AspectJ切點函式之@annotation()
@annotation()概述 @annotation表示標註了某個註解的所有方法。 下面通過一個例項說明@annotation()的用法。 AnnotationTestAspect
Spring進階之路(10)-Advice簡介以及通過cglib生成AOP代理物件
Advice簡介 1. Before:在目標方法執行之前執行織入,如果Before的處理中沒有進行特殊的處理,那麼目標方法最終會執行,但是如果想要阻止目標方法執行時,可以通過丟擲一個異常來實現,Be
【SSH進階之路】Struts + Spring + Hibernate 進階開端(一)
height 一段 ioc 效率 陽光大道 面向對象的思想 text ase 們的 Long Long ago。就聽說過SSH。起初還以為是一個東東,詳細內容更是不詳,總認為高端大氣上檔次,經過學習之後才發現,不不過高大上,更是低調奢華有內涵,經過一段時間的
C#進階之AOP
com aop uid spa amp ace 進階 c# php http://pic.cnhubei.com/space.php?uid=4614&do=album&id=1349648http://pic.cnhubei.com/space.php?u
Spring Boot 進階之Web進階 學習 - 單元測試
自動生成 添加 學習 one 類文件 dma AC mock ring 可在類文件中,右鍵->GO TO->Test 自動生成測試文件 1.添加測試註解 簡單方法測試 @RunWith(SpringRunner.class)@SpringBootTes
Spring Cloud 進階之路 -- 訊息匯流排 Spring Cloud Bus 配置手動重新整理和動態自動重新整理
Spring Cloud Bus 配置步驟: 1、Spring Cloud Config 專案引入依賴,新增配置,配置暴露 endpoints 2、啟動Config 專案,註冊到Eureka,自動新增RabbitMQ佇列 3、客戶端的order應用引入依賴及配置,啟動Con