📜  Spring AOP-实现

📅  最后修改于: 2020-11-11 05:16:21             🧑  作者: Mango


Spring支持@AspectJ批注样式方法和基于模式的方法来实现自定义方面。

基于XML模式

使用常规类以及基于XML的配置来实现方面。

要使用本节中描述的AOP名称空间标记,您需要导入spring AOP模式,如下所述-




   


声明一个方面

使用元素声明一个方面,并使用ref属性引用后备bean,如下所示。


   
   ...
   



   ...

就像在前几章中看到的那样,在这里将配置“ aBean”并注入依赖项。

声明一个PointCut

PointCut帮助确定要使用不同建议执行的感兴趣的连接点(即方法)。在使用基于XML Schema的配置时,PointCut的定义如下-


   

   
      ...
   



   ...

下面的示例定义一个名为’businessService’的PointCut,该PointCut将与com.tutorialspoint包下的Student类中可用的getName()方法的执行匹配。


   

   
   ...
   



   ...

宣告建议

您可以使用元素,在中声明五个建议中的任何一个,如下所示。


   
      

      
      

      
      

      
      
      

      
      
      

      
      
   ...
   



   ...

您可以将相同的doRequiredTask或不同的方法用于不同的建议。这些方法将被定义为Aspect模块的一部分。

基于@AspectJ

@AspectJ是一种将方面声明为带有Java 5批注的常规Java类的样式。通过在基于XML Schema的配置文件中包含以下元素,可以启用@AspectJ支持。


声明一个方面

Aspects类与任何其他普通bean一样,并且可以像其他任何类一样具有方法和字段,不同之处在于它们将使用@Aspect进行如下注释。

package org.xyz;

import org.aspectj.lang.annotation.Aspect;

@Aspect
public class AspectModule {

}

它们将像其他任何bean一样以XML进行配置,如下所示。


   

声明一个PointCut

PointCut帮助确定要使用不同建议执行的感兴趣的连接点(即方法)。在使用基于@AspectJ的配置时,PointCut声明包含两个部分-

  • 一个PointCut表达式,它精确确定我们感兴趣的方法执行。

  • 一个PointCut签名,包括名称和任意数量的参数。该方法的实际主体是无关紧要的,实际上应该为空。

下面的示例定义一个名为’businessService’的PointCut,该PointCut将与com.xyz.myapp.service包下的类中可用的每个方法的执行匹配。

import org.aspectj.lang.annotation.PointCut;

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

下面的示例定义一个名为“ getname”的PointCut,该PointCut将与com.tutorialspoint包下的Student类中可用的getName()方法的执行匹配。

import org.aspectj.lang.annotation.PointCut;

@PointCut("execution(* com.tutorialspoint.Student.getName(..))") 
private void getname() {}

宣告建议

您可以使用@ {ADVICE-NAME}注释声明以下五个建议中的任何一个。假设您已经定义了PointCut签名方法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(){
   ...
}

您可以为任何建议内联定义PointCut。以下是为预先建议定义内联PointCut的示例。

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