
- Spring AOP 教程
- Spring AOP - 首頁
- Spring AOP - 概述
- Spring AOP - 環境搭建
- Spring AOP - 核心概念
- Spring AOP - 通知型別
- Spring AOP - 實現
- 基於XML配置的示例
- Spring AOP - 應用
- Spring AOP - 切點方法
- Spring AOP - 前置通知
- Spring AOP - 後置通知
- Spring AOP - 返回後通知
- Spring AOP - 異常丟擲後通知
- Spring AOP - 環繞通知
- 基於註解的示例
- Spring AOP - 應用
- Spring AOP - 切點方法
- Spring AOP - 前置切面
- Spring AOP - 後置通知
- Spring AOP - 返回後通知
- Spring AOP - 異常丟擲後通知
- Spring AOP - 環繞通知
- Spring AOP 高階特性
- Spring AOP - 代理
- Spring AOP - 自定義註解
- Spring AOP 有用資源
- Spring AOP - 快速指南
- Spring AOP - 有用資源
- Spring AOP - 討論
Spring AOP - 實現
Spring 支援@AspectJ 註解風格方法和基於schema的方法來實現自定義切面。
基於XML Schema
切面使用常規類以及基於XML的配置來實現。
要使用本節中描述的AOP名稱空間標籤,您需要匯入Spring AOP schema,如下所示:
<?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-3.0.xsd http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-3.0.xsd "> <!-- bean definition & AOP specific configuration --> </beans>
宣告切面
使用<aop:aspect>元素宣告一個切面,並使用ref屬性引用支援bean,如下所示。
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
這裡“aBean”將像您在前面章節中看到的那樣,被配置和依賴注入,就像任何其他Spring bean一樣。
宣告切點
切點有助於確定要與不同通知一起執行的感興趣的連線點(即方法)。在使用基於XML Schema的配置時,切點將如下定義:
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> <aop:pointcut id = "businessService" expression = "execution(* com.xyz.myapp.service.*.*(..))"/> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
以下示例定義了一個名為“businessService”的切點,該切點將匹配com.tutorialspoint包下Student類中getName()方法的執行。
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> <aop:pointcut id = "businessService" expression = "execution(* com.tutorialspoint.Student.getName(..))"/> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
宣告通知
您可以在<aop:aspect>內使用<aop:{通知名稱}>元素宣告五種通知中的任何一種,如下所示。
<aop:config> <aop:aspect id = "myAspect" ref = "aBean"> <aop:pointcut id = "businessService" expression = "execution(* com.xyz.myapp.service.*.*(..))"/> <!-- a before advice definition --> <aop:before pointcut-ref = "businessService" method = "doRequiredTask"/> <!-- an after advice definition --> <aop:after pointcut-ref = "businessService" method = "doRequiredTask"/> <!-- an after-returning advice definition --> <!--The doRequiredTask method must have parameter named retVal --> <aop:after-returning pointcut-ref = "businessService" returning = "retVal" method = "doRequiredTask"/> <!-- an after-throwing advice definition --> <!--The doRequiredTask method must have parameter named ex --> <aop:after-throwing pointcut-ref = "businessService" throwing = "ex" method = "doRequiredTask"/> <!-- an around advice definition --> <aop:around pointcut-ref = "businessService" method = "doRequiredTask"/> ... </aop:aspect> </aop:config> <bean id = "aBean" class = "..."> ... </bean>
您可以對不同的通知使用相同的doRequiredTask或不同的方法。這些方法將定義為切面模組的一部分。
基於@AspectJ
@AspectJ 指的是將切面宣告為用Java 5註解註釋的常規Java類的一種風格。透過在基於XML Schema的配置檔案中包含以下元素來啟用@AspectJ支援。
<aop:aspectj-autoproxy/>
宣告切面
切面類就像任何其他普通bean一樣,可以像任何其他類一樣擁有方法和欄位,不同之處在於它們將用@Aspect註解,如下所示。
package org.xyz; import org.aspectj.lang.annotation.Aspect; @Aspect public class AspectModule { }
它們將像任何其他bean一樣在XML中配置,如下所示。
<bean id = "myAspect" class = "org.xyz.AspectModule"> <!-- configure properties of aspect here as normal --> </bean>
宣告切點
切點有助於確定要與不同通知一起執行的感興趣的連線點(即方法)。在使用基於@AspectJ的配置時,切點宣告包含兩部分:
一個切點表示式,它確定我們感興趣的哪些方法執行。
一個切點簽名,包括一個名稱和任意數量的引數。方法的實際主體無關緊要,實際上應該為空。
以下示例定義了一個名為“businessService”的切點,該切點將匹配com.xyz.myapp.service包下類中每個方法的執行。
import org.aspectj.lang.annotation.Pointcut; @Pointcut("execution(* com.xyz.myapp.service.*.*(..))") // expression private void businessService() {} // signature
以下示例定義了一個名為“getname”的切點,該切點將匹配com.tutorialspoint包下Student類中getName()方法的執行。
import org.aspectj.lang.annotation.Pointcut; @Pointcut("execution(* com.tutorialspoint.Student.getName(..))") private void getname() {}
宣告通知
您可以使用@{通知名稱}註解宣告五種通知中的任何一種,如下所示。這假設您已經定義了一個切點簽名方法businessService()。
@Before("businessService()") public void doBeforeTask(){ ... } @After("businessService()") public void doAfterTask(){ ... } @AfterReturning(Pointcut = "businessService()", returning = "retVal") public void doAfterReturnningTask(Object retVal){ // you can intercept retVal here. ... } @AfterThrowing(Pointcut = "businessService()", throwing = "ex") public void doAfterThrowingTask(Exception ex){ // you can intercept thrown exception here. ... } @Around("businessService()") public void doAroundTask(){ ... }
您可以為任何通知內聯定義切點。以下是為前置通知定義內聯切點的示例。
@Before("execution(* com.xyz.myapp.service.*.*(..))") public doBeforeTask(){ ... }