Spring - AOP - AspectJ annotation示例

原文地址:https://mkyong.com/spring3/spring-aop-aspectj-annotation-example/

在本教程中,我们向您展示如何将AspectJ注释与Spring AOP框架集成在一起。
简单来说,Spring AOP + AspectJ使您可以轻松地拦截方法。

常见的AspectJ注释:

  • @Before – 在方法执行之前运行
  • @After – 方法返回结果后运行
  • @AfterReturning – 在方法返回结果之后运行,也将拦截返回的结果。
  • @AfterThrowing – 在方法抛出异常后运行
  • @Around – 运行方法执行,结合以上所有三个建议

注意:对于没有AspectJ支持的Spring AOP,请阅读。Spring - AOP - Advice

1.目录结构

请参阅本示例的目录结构。

Spring - AOP - AspectJ annotation示例_第1张图片
目录结构.png

2.项目依赖

要启用AspectJ,您需要aspectjrt.jar,aspectjweaver.jar和spring-aop.jar。
请参阅以下Maven pom.xml文件

从Spring 2.0开始支持AspectJ
此示例使用的是Spring 3,但自Spring 2.0开始支持AspectJ功能。

文件:pom.xml



    
        3.0.5.RELEASE
    

    

        
            org.springframework
            spring-core
            ${spring.version}
        

        
            org.springframework
            spring-context
            ${spring.version}
        

        
        
            org.springframework
            spring-aop
            ${spring.version}
        

        
            org.aspectj
            aspectjrt
            1.6.11
        
        
        
            org.aspectj
            aspectjweaver
            1.6.11
        
        
    

3. Spring Beans

package com.mkyong.customer.bo;

public interface CustomerBo {

    void addCustomer();
    
    String addCustomerReturnValue();
    
    void addCustomerThrowException() throws Exception;
    
    void addCustomerAround(String name);
}
package com.mkyong.customer.bo.impl;

import com.mkyong.customer.bo.CustomerBo;

public class CustomerBoImpl implements CustomerBo {

    public void addCustomer(){
        System.out.println("addCustomer() is running ");
    }
    
    public String addCustomerReturnValue(){
        System.out.println("addCustomerReturnValue() is running ");
        return "abc";
    }
    
    public void addCustomerThrowException() throws Exception {
        System.out.println("addCustomerThrowException() is running ");
        throw new Exception("Generic Error");
    }
    
    public void addCustomerAround(String name){
        System.out.println("addCustomerAround() is running, args : " + name);
    }
}

4.启用AspectJ

在Spring配置文件中,放入“ ”,然后定义您的Aspect(拦截器)和普通bean。

文件:Spring-Customer.xml



    

    

    
    

4. AspectJ @Before

在下面的示例中,将在执行customerBo接口addCustomer()方法之前执行logBefore()方法。

文件:LoggingAspect.java

package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;

@Aspect
public class LoggingAspect {

    @Before("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
    public void logBefore(JoinPoint joinPoint) {

        System.out.println("logBefore() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");
    }

}

运行

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
    customer.addCustomer();

输出

logBefore() is running!
hijacked : addCustomer
******
addCustomer() is running 

5. AspectJ @After

在下面的示例中,将在执行customerBo接口addCustomer()方法之后执行logAfter()方法。

文件:LoggingAspect.java

```
package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.After;

@Aspect
public class LoggingAspect {

    @After("execution(* com.mkyong.customer.bo.CustomerBo.addCustomer(..))")
    public void logAfter(JoinPoint joinPoint) {

        System.out.println("logAfter() is running!");
        System.out.println("hijacked : " + joinPoint.getSignature().getName());
        System.out.println("******");

    }

}

运行

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomer();

输出

addCustomer() is running 
logAfter() is running!
hijacked : addCustomer
******

6. AspectJ @AfterReturning

在下面的示例中,将在执行customerBo接口addCustomerReturnValue()方法之后执行logAfterReturning()方法。
另外,您可以使用“returning”属性截取返回的值。

要拦截返回的值,“returning”属性(结果)的值必须与方法参数(结果)相同。

文件:LoggingAspect.java

package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterReturning;

@Aspect
public class LoggingAspect {

   @AfterReturning(
      pointcut = "execution(* com.mkyong.customer.bo.CustomerBo.addCustomerReturnValue(..))",
      returning= "result")
   public void logAfterReturning(JoinPoint joinPoint, Object result) {

    System.out.println("logAfterReturning() is running!");
    System.out.println("hijacked : " + joinPoint.getSignature().getName());
    System.out.println("Method returned value is : " + result);
    System.out.println("******");

   }

}

运行

CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
customer.addCustomerReturnValue();

输出

addCustomerReturnValue() is running 
logAfterReturning() is running!
hijacked : addCustomerReturnValue
Method returned value is : abc
******

7. AspectJ @AfterThrowing

在下面的示例中,如果customerBo接口addCustomerThrowException()方法引发异常,则将执行logAfterThrowing()方法。

文件:LoggingAspect.java

package com.mkyong.aspect;

import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.AfterThrowing;

@Aspect
public class LoggingAspect {

   @AfterThrowing(
      pointcut = "execution(* com.mkyong.customer.bo.CustomerBo.addCustomerThrowException(..))",
      throwing= "error")
    public void logAfterThrowing(JoinPoint joinPoint, Throwable error) {

    System.out.println("logAfterThrowing() is running!");
    System.out.println("hijacked : " + joinPoint.getSignature().getName());
    System.out.println("Exception : " + error);
    System.out.println("******");

    }
}

运行

CustomerBo customer = (CustomerBo)appContext.getBean("customerBo");
customer.addCustomerThrowException();

输出

addCustomerThrowException() is running 
logAfterThrowing() is running!
hijacked : addCustomerThrowException
Exception : java.lang.Exception: Generic Error
******
Exception in thread "main" java.lang.Exception: Generic Error
    //...

8.AspectJ @Around

在下面的示例中,logAround()方法将在customerBo接口,addCustomerAround()方法之前执行,并且您必须定义“ joinPoint.proceed();”以控制拦截器何时应将控件返回到原始addCustomerAround()方法。

文件:LoggingAspect.java

package com.mkyong.aspect;

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Around;

@Aspect
public class LoggingAspect {

   @Around("execution(* com.mkyong.customer.bo.CustomerBo.addCustomerAround(..))")
   public void logAround(ProceedingJoinPoint joinPoint) throws Throwable {

    System.out.println("logAround() is running!");
    System.out.println("hijacked method : " + joinPoint.getSignature().getName());
    System.out.println("hijacked arguments : " + Arrays.toString(joinPoint.getArgs()));
        
    System.out.println("Around before is running!");
    joinPoint.proceed(); //continue on the intercepted method
    System.out.println("Around after is running!");
        
    System.out.println("******");

   }
    
}

运行

CustomerBo customer = (CustomerBo)appContext.getBean("customerBo");
customer.addCustomerAround("mkyong");

输出

logAround() is running!
hijacked method : addCustomerAround
hijacked arguments : [mkyong]
Around before is running!
addCustomerAround() is running, args : mkyong
Around after is running!
******

总结

始终建议使用功耗最低的AsjectJ注解。

你可能感兴趣的:(Spring - AOP - AspectJ annotation示例)