分享

java学习笔记10 - 以@AspectJ方式在Spring中实现AOP

 埃德温会馆 2016-01-25

1. Spring AOP介绍

Spring 提供了很多的实现AOP的方式,有Spring 接口方式,schema配置方式和注解的三种,从Spring 2.0开始,可以使用基于schema及@AspectJ的方式来实现AOP,本文以一个简单的实例介绍了如何以@AspectJ方式在Spring中实现AOP。由于@Aspect是基于注解的,因此要求支持注解的5.0版本以上的JDK。


2.Spring AOP环境

要在项目中使用Spring AOP 则需要在项目中导入除了spring jar包之外,还有aspectjweaver.jar,aspectjrt.jar 和cglib.jar 。

在Spring MVC基本上只需另外加上aspectjweaver.jar和cglib.jar就可以了

  1. <dependency>  
  2.     <groupId>org.aspectj</groupId>  
  3.     <artifactId>aspectjweaver</artifactId>  
  4.     <version>1.7.1</version>  
  5. </dependency>  
  6.   
  7. <dependency>  
  8.     <groupId>cglib</groupId>  
  9.     <artifactId>cglib</artifactId>  
  10.     <version>2.2.2</version>  
  11. </dependency>  

好了,前提工作准备完成。


3. 实例

这个实例是利用AOP实现对执行方法的环绕增强,即在执行目标方法前后各执行一段我们写好的方法,来达到执行前过滤,执行后记录log的功能

a.目标方法代码

  1. @Controller  
  2. public class AccountApiController {  
  3.       
  4.     @ResponseBody  
  5.     @RequestMapping(value="/openapi/v1/account/kp")  
  6.     public String kp(HttpServletRequest request) {  
  7.         System.out.println("kp:123");  
  8.         return "kp:123";  
  9.     }  
  10.       
  11. }  

b.环绕增强的@AspectJ代码

  1. @Aspect  
  2. public class ApiAspect {  
  3.   
  4.     private static final Logger logger = LoggerFactory.getLogger("com.xxx.log");  
  5.   
  6.     //通过within匹配目标方法的class  
  7.     @Around("within(com.xxx.api.*Controller)")  
  8.     public String arountAction(ProceedingJoinPoint pjp){  
  9.           
  10.         //接口request参数检查,  
  11.         HttpServletRequest request = (HttpServletRequest) pjp.getArgs()[0];  
  12.         try {  
  13.             //TODO check  
  14.         } catch (Exception e) {  
  15.             //TODO log & return  
  16.         }  
  17.   
  18.         String result = null;  
  19.         try {  
  20.             //执行目标方法  
  21.             result = (String) pjp.proceed();  
  22.             //TODO log  
  23.         } catch (Throwable e) {  
  24.             //TODO log & return  
  25.         }  
  26.           
  27.         return result;  
  28.     }  
  29. }  
c.Spring xml配置

  1. <aop:aspectj-autoproxy />  
  2. <beans:bean class="com.xxx.api.ApiAspect" />  
  3. <context:component-scan base-package="com.xxx.api.*" />  

这样就实现了所需的功能 ,AOP的优点就是对目标方法代码不做任何改动,就可以实现前后处理,另外在b中也可以用@Before,@After等其它注解来实现不同的功能,下面就介绍下@AspectJ的详细用法

4. @AspectJ的详细用法

在Spring AOP中目前只有执行方法这一个连接点,Spring AOP支持的AspectJ切入点指示符如下:


一些常见的切入点的例子 
execution(public * * (. .))    任意公共方法被执行时,执行切入点函数。 
execution( * set* (. .))   任何以一个“set”开始的方法被执行时,执行切入点函数。 
execution( * com.demo.service.AccountService.* (. .))  当接口AccountService 中的任意方法被执行时,执行切入点函数。 
execution( * com.demo.service.*.* (. .))  当service 包中的任意方法被执行时,执行切入点函数。 within(com.demo.service.*)  在service 包里的任意连接点。 within(com.demo.service. .*)  在service 包或子包的任意连接点。
this(com.demo.service.AccountService) 实现了AccountService 接口的代理对象的任意连接点。 
target(com.demo.service.AccountService) 实现了AccountService 接口的目标对象的任意连接点。 
args(java.io.Serializable)  任何一个只接受一个参数,且在运行时传入参数实现了 Serializable 接口的连接点

增强的方式:

@Before:方法前执行

@AfterReturning:运行方法后执行

@AfterThrowing:Throw后执行

@After:无论方法以何种方式结束,都会执行(类似于finally)

@Around:环绕执行


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多