鍍金池/ 教程/ Java/ Spring AOP實現(xiàn)
Spring AOP基于XML的After Advice
Spring AOP基于XML的Before Advice
Spring AOP基于XML的After Returning Advice
Spring AOP基于注解的切入點
Spring AOP基于XML的After Throwing Advice
Spring AOP實現(xiàn)
Spring AOP基于注解的Around通知
Spring AOP環(huán)境安裝設置
Spring AOP自定義注解
Spring AOP代理
Spring AOP基于XML的切入點
Spring AOP基于XML的Around Advice
Spring AOP通知類型
Spring AOP基于XML的應用程序
Spring AOP基于注解的After Advice
Spring AOP基于注解的Before Advice
Spring AOP基于注解的AfterThrowing
Spring AOP教程
Spring AOP基于注解的After Returning Advice
Spring AOP核心概念
Spring AOP基于注解的應用

Spring AOP實現(xiàn)

Spring支持使用@AspectJ注釋樣式方法和基于模式的方法來實現(xiàn)自定義方面。

基于XML模式

方面(Aspects)使用常規(guī)類以及基于XML的配置來實現(xiàn)。
要使用本節(jié)中描述的aop命名空間標簽,您需要按照以下所述導入spring-aop模式:

<?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>

聲明一個方面(Aspects)

使用<aop:aspect>元素聲明一個方面(Aspects),并使用ref屬性引用后臺bean,如下所示:

<aop:config>
   <aop:aspect id="myAspect" ref="aBean">
   ...
   </aop:aspect>
</aop:config>

<bean id="aBean" class="...">
...
</bean>

這個“aBean”將被配置和依賴注入就像任何其他的Spring Bean一樣,就像在前幾章中看到的一樣。

聲明一個切入點

切入點(pointcut)有助于確定要用不同建議執(zhí)行的關聯(lián)點(即方法)。 在使用基于XML模式的配置時,切入點將定義如下:

<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.yiibai包中Student類中的getName()方法的執(zhí)行:

<aop:config>
   <aop:aspect id="myAspect" ref="aBean">

   <aop:pointcut id="businessService"
      expression="execution(* com.yiibai.Student.getName(..))"/>
   ...
   </aop:aspect>
</aop:config>

<bean id="aBean" class="...">
...
</bean>

聲明通知

您可以使用<aop:{ADVICE NAME}>元素在<aop:aspect>內(nèi)的五個通知中的任何一個聲明如下:

<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方法注釋為Java 5注釋的常規(guī)Java類的方式。 @AspectJ是指將Java方法注釋為Java 5注釋的常規(guī)Java類的方式。通過在基于XML Schema的配置文件中包含以下元素來啟用@AspectJ支持。

<aop:aspectj-autoproxy/>

聲明一個方面(aspect)

方面(aspect)的類就像任何其他正常的bean一樣,并且可以像任何其他類一樣具有方法和字段,不過它們使用@Aspect進行注釋,如下所示:

package org.xyz;

import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AspectModule {

}

它們就像任何其他以XML格式配置的bean一樣,如下所示:

<bean id="myAspect" class="org.xyz.AspectModule">
   <!-- configure properties of aspect here as normal -->
</bean>

聲明一個切入點

切入點(pointcut)有助于確定要用不同通知執(zhí)行的關聯(lián)點(即方法)。 在使用基于@AspectJ的配置時,切入點聲明有兩部分:

  • 一個切入點表達式,確定哪些方法執(zhí)行。
  • 切入點簽名包括名稱和任意數(shù)量的參數(shù)。 該方法的實體是無關緊要的,也可以是空的。

以下示例定義了一個名為“businessService”的切入點,該切入點將匹配com.xyz.myapp.service包下的類中可用的每個方法的執(zhí)行:

import org.aspectj.lang.annotation.Pointcut;

@Pointcut("execution(* com.xyz.myapp.service.*.*(..))") // expression 
private void businessService() {}  // signature

以下示例定義了一個名為“getname”的切入點,該切入點將與com.yiibai包下的Student類中的getName()方法的執(zhí)行相匹配:

import org.aspectj.lang.annotation.Pointcut;

@Pointcut("execution(* com.yiibai.Student.getName(..))") 
private void getname() {}

聲明通知

您可以使用@{ADVICE-NAME}注釋在以下所述的五個建議中聲明任何一個。假設您已經(jīng)定義了一個切入點簽名方法為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(){
 ...
}

可以為任何通知定義切入點內(nèi)嵌。 下面是一個為之前通知定義的內(nèi)聯(lián)切入點的示例:

@Before("execution(* com.xyz.myapp.service.*.*(..))")
public doBeforeTask(){
 ...
}