我们将向你展示如何将AspectJ注解集成到Spring AOP框架。在这个Spring AOP+ AspectJ 示例中,让您轻松实现拦截方法。

常见AspectJ的注解:
  1. @Before – 方法执行前运行
  2. @After – 运行在方法返回结果后
  3. @AfterReturning – 运行在方法返回一个结果后,在拦截器返回结果。
  4. @AfterThrowing – 运行方法在抛出异常后,
  5. @Around – 围绕方法执行运行,结合以上这三个通知。
 

1. 目录结构

看到这个例子的目录结构。
 

2. Spring Beans

普通 bean 中有几个方法,后来通过 AspectJ 注解拦截。
  1. package com.yiibai.customer.bo;
  2.  
  3. public interface CustomerBo {
  4.  
  5. void addCustomer();
  6.  
  7. String addCustomerReturnValue();
  8.  
  9. void addCustomerThrowException() throws Exception;
  10.  
  11. void addCustomerAround(String name);
  12. }
  13.  
  14. package com.yiibai.customer.bo.impl;
  15.  
  16. import com.yiibai.customer.bo.CustomerBo;
  17.  
  18. public class CustomerBoImpl implements CustomerBo {
  19.  
  20. public void addCustomer(){
  21. System.out.println("addCustomer() is running ");
  22. }
  23.  
  24. public String addCustomerReturnValue(){
  25. System.out.println("addCustomerReturnValue() is running ");
  26. return "abc";
  27. }
  28.  
  29. public void addCustomerThrowException() throws Exception {
  30. System.out.println("addCustomerThrowException() is running ");
  31. throw new Exception("Generic Error");
  32. }
  33.  
  34. public void addCustomerAround(String name){
  35. System.out.println("addCustomerAround() is running, args : " + name);
  36. }
  37. }

4. 启用AspectJ

在 Spring 配置文件,把“<aop:aspectj-autoproxy />”,并定义Aspect(拦截)和普通的bean。

File : applicationContext.xml

  1. <beans xmlns="http://www.springframework.org/schema/beans"
  2. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  3. xmlns:aop="http://www.springframework.org/schema/aop"
  4. xsi:schemaLocation="http://www.springframework.org/schema/beans
  5. http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
  6. http://www.springframework.org/schema/aop
  7. http://www.springframework.org/schema/aop/spring-aop-3.0.xsd ">
  8.  
  9. <aop:aspectj-autoproxy />
  10.  
  11. <bean id="customerBo" class="com.yiibai.customer.bo.impl.CustomerBoImpl" />
  12.  
  13. <!-- Aspect -->
  14. <bean id="logAspect" class="com.yiibai.aspect.LoggingAspect" />
  15.  
  16. </beans>

4. AspectJ @Before

在下面例子中,logBefore()方法将在 customerBo接口的 addCustomer()方法的执行之前被执行。
AspectJ的“切入点”是用来声明哪种方法将被拦截,应该参考Spring AOP切入点指南,支持切入点表达式的完整列表。

File : LoggingAspect.java

  1. package com.yiibai.aspect;
  2.  
  3. import org.aspectj.lang.JoinYiibai;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Before;
  6.  
  7. @Aspect
  8. public class LoggingAspect {
  9.  
  10. @Before("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))")
  11. public void logBefore(JoinYiibai joinYiibai) {
  12.  
  13. System.out.println("logBefore() is running!");
  14. System.out.println("hijacked : " + joinYiibai.getSignature().getName());
  15. System.out.println("******");
  16. }
  17.  
  18. }

运行

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

输出结果

  1. logBefore() is running!
  2. hijacked : addCustomer
  3. ******
  4. addCustomer() is running

5. AspectJ @After

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

File : LoggingAspect.java

  1. package com.yiibai.aspect;
  2.  
  3. import org.aspectj.lang.JoinYiibai;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.After;
  6.  
  7. @Aspect
  8. public class LoggingAspect {
  9.  
  10. @After("execution(* com.yiibai.customer.bo.CustomerBo.addCustomer(..))")
  11. public void logAfter(JoinYiibai joinYiibai) {
  12.  
  13. System.out.println("logAfter() is running!");
  14. System.out.println("hijacked : " + joinYiibai.getSignature().getName());
  15. System.out.println("******");
  16.  
  17. }
  18.  
  19. }

运行它

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

输出结果

  1. addCustomer() is running
  2. logAfter() is running!
  3. hijacked : addCustomer
  4. ******

6. AspectJ @AfterReturning

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

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

File : LoggingAspect.java

  1. package com.yiibai.aspect;
  2.  
  3. import org.aspectj.lang.JoinYiibai;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.AfterReturning;
  6.  
  7. @Aspect
  8. public class LoggingAspect {
  9.  
  10. @AfterReturning(
  11. pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerReturnValue(..))",
  12. returning= "result")
  13. public void logAfterReturning(JoinYiibai joinYiibai, Object result) {
  14.  
  15. System.out.println("logAfterReturning() is running!");
  16. System.out.println("hijacked : " + joinYiibai.getSignature().getName());
  17. System.out.println("Method returned value is : " + result);
  18. System.out.println("******");
  19. }
  20. }

运行它

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

输出结果

  1. addCustomerReturnValue() is running
  2. logAfterReturning() is running!
  3. hijacked : addCustomerReturnValue
  4. Method returned value is : abc
  5. ******

7. AspectJ @AfterReturning

在下面的例子中,如果 customerBo 接口的addCustomerThrowException()方法抛出异常logAfterThrowing()方法将被执行。

File : LoggingAspect.java

  1. package com.yiibai.aspect;
  2.  
  3. import org.aspectj.lang.JoinYiibai;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.AfterThrowing;
  6.  
  7. @Aspect
  8. public class LoggingAspect {
  9.  
  10. @AfterThrowing(
  11. pointcut = "execution(* com.yiibai.customer.bo.CustomerBo.addCustomerThrowException(..))",
  12. throwing= "error")
  13. public void logAfterThrowing(JoinYiibai joinYiibai, Throwable error) {
  14.  
  15. System.out.println("logAfterThrowing() is running!");
  16. System.out.println("hijacked : " + joinYiibai.getSignature().getName());
  17. System.out.println("Exception : " + error);
  18. System.out.println("******");
  19.  
  20. }
  21. }

运行它

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

输出结果

  1. addCustomerThrowException() is running
  2. logAfterThrowing() is running!
  3. hijacked : addCustomerThrowException
  4. Exception : java.lang.Exception: Generic Error
  5. ******
  6. Exception in thread "main" java.lang.Exception: Generic Error
  7. //...

8. AspectJ @Around

在下面例子中,logAround()方法将在customerBo接口的addCustomerAround()方法执行之前执行, 必须定义“joinYiibai.proceed();” 控制何时拦截器返回控制到原来的addCustomerAround()方法。

File : LoggingAspect.java

  1. package com.yiibai.aspect;
  2.  
  3. import org.aspectj.lang.ProceedingJoinYiibai;
  4. import org.aspectj.lang.annotation.Aspect;
  5. import org.aspectj.lang.annotation.Around;
  6.  
  7. @Aspect
  8. public class LoggingAspect {
  9.  
  10. @Around("execution(* com.yiibai.customer.bo.CustomerBo.addCustomerAround(..))")
  11. public void logAround(ProceedingJoinYiibai joinYiibai) throws Throwable {
  12.  
  13. System.out.println("logAround() is running!");
  14. System.out.println("hijacked method : " + joinYiibai.getSignature().getName());
  15. System.out.println("hijacked arguments : " + Arrays.toString(joinYiibai.getArgs()));
  16.  
  17. System.out.println("Around before is running!");
  18. joinYiibai.proceed(); //continue on the intercepted method
  19. System.out.println("Around after is running!");
  20.  
  21. System.out.println("******");
  22.  
  23. }
  24.  
  25. }

运行它

  1. CustomerBo customer = (CustomerBo) appContext.getBean("customerBo");
  2. customer.addCustomerAround("yiibai");

输出结果

  1. logAround() is running!
  2. hijacked method : addCustomerAround
  3. hijacked arguments : [yiibai]
  4. Around before is running!
  5. addCustomerAround() is running, args : yiibai
  6. Around after is running!
  7. ******

总结

它总是建议采用最少 AspectJ 注解。这是关于Spring AspectJ 的一篇相当长的文章。进一步的解释和例子,请访问下面的参考链接。
下载源代码 – http://pan.baidu.com/s/1boo4f9P

Spring学习(十八)----- Spring AOP+AspectJ注解实例的更多相关文章

  1. spring学习 十八 spring的声明事物

    1.编程式事务: 1.1 由程序员编程事务控制代码.commit与rollback都需要程序员决定在哪里调用,例如jdbc中conn.setAutoCimmit(false),conn.commit( ...

  2. Spring学习十四----------Spring AOP实例

    © 版权声明:本文为博主原创文章,转载请注明出处 实例 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4.0 ...

  3. Spring学习(八)AOP详解

    文章更新时间:2020/04/06 一.一个例子 在上面的例子中,包租婆的核心业务就是签合同,收房租,那么这就够了,灰色框起来的部分都是重复且边缘的事,交给中介商就好了,这就是 AOP 的一个思想:让 ...

  4. Spring学习(十六)----- Spring AOP实例(Pointcut(切点),Advisor)

    在上一个Spring AOP通知的例子,一个类的整个方法被自动拦截.但在大多数情况下,可能只需要一种方式来拦截一个或两个方法,这就是为什么引入'切入点'的原因.它允许你通过它的方法名来拦截方法.另外, ...

  5. Spring学习(十五)----- Spring AOP通知实例 – Advice

    Spring AOP(面向方面编程)框架,用于在模块化方面的横切关注点.简单得说,它只是一个拦截器拦截一些过程,例如,当一个方法执行,Spring AOP 可以劫持一个执行的方法,在方法执行之前或之后 ...

  6. Spring学习十五----------Spring AOP API的Pointcut、advice及 ProxyFactoryBean相关内容

    © 版权声明:本文为博主原创文章,转载请注明出处 实例: 1.项目结构 2.pom.xml <project xmlns="http://maven.apache.org/POM/4. ...

  7. Spring学习(十九)----- Spring的五种事务配置详解

    前段时间对Spring的事务配置做了比较深入的研究,在此之间对Spring的事务配置虽说也配置过,但是一直没有一个清楚的认识.通过这次的学习发觉Spring的事务配置只要把思路理清,还是比较好掌握的. ...

  8. spring学习 十六 spring加载属性文件

    第一步:创建一个properties文件,以数据库链接作为实例db.properties jdbc.url=jdbc:mysql://192.168.153.128:3306/mybaties?cha ...

  9. spring学习 十五 spring的自动注入

    一  :在 Spring 配置文件中对象名和 ref=”id” ,id 名相同使用自动注入,可以不配置<property/>,对应的注解@Autowired的作用 二: 两种配置办法 (1 ...

随机推荐

  1. win10WLAN没有有效的ip配置

    方案一:将路由器和猫重启一下,一般都可以解决了!方案二:1.在开始菜单上单击鼠标右键,选择“命令提示符(管理员)”,如果没有找到这个选项,通过cortana搜索cmd,右键以管理员身份运行,还可以进入 ...

  2. 【Excel】坐下,VLOOKUP基本操作

    坐下,VLOOKUP基本操作   VLOOKUP如何使用我就不在这里详细介绍了,简单说一下好了.     如上图,第一个填写你要查找的值,第二个空选取你查找的范围,第三个空填你要得到第几列的值,最后选 ...

  3. Spring+微信小程序 卡券打通

    近期公司项目需要使用到微信卡券模块,主要做的是在小程序打通微信卡券,实现小程序领取卡券的功能效果. 简单说下涉及的东西: Springboot—使用springboot做后端接口,非常便捷 并且根本是 ...

  4. 实践和感悟 - scala向下转型和减少穷举

    工作中的问题总结: 问题一:scala 之向下转型 引言:假如在复杂的业务逻辑中,变量的类型不能确认,只能给个接口类型,这样数据类型推导不会错误,但是后面要使用实现类的类型时,你却发现转不过来了? 对 ...

  5. LA 3938 动态最大连续区间 线段树

    思路很清晰,实现很繁琐.分析过程可以参考LRJ,自己的总结晚些放. #include <cstdio> #include <cstring> #include <algo ...

  6. APP的案例分析

    很多同学有误解,软件项目管理是否就是理论课?或者是几个牛人拼命写代码,其他人打酱油的课?要不然就是学习一个程序语言,搞一个职业培训的课?都不对,软件项目管理有理论,有实践,更重要的是分析,思辨,总结. ...

  7. Anaconda 包管理工具 conda 进行虚拟环境管理入门

    在基于 python 进行数据分析.机器学习等领域的实践和学习时,由于代码的更迭和更新,运行他人实现的代码或尝试安装新的工具库时往往需要指定特定版本的其他工具库,以满足特定环境的构建条件.而将同一工具 ...

  8. 实现body背景拉伸自适应 兼容chrome ie7,8,9.ie6未测试

    html, body {/*此部分支持chrome,应该也支持firefox*/ background: rgb(246,248,249); background: url('/styles/imag ...

  9. httpd:RSA certificate configured for SERVER does NOT include an ID which matches the server name

    这个是因为ssl认证丢失了密钥的问题,Apache的默认配置文件加载了mod_ssl模块,而且指定密钥对儿的位置,就是我测试salt-api时创建密钥对儿的位置.而且还有一个错误就是我密钥对儿指定的h ...

  10. centos6.5升级内核到3.0

    因为是使用centos6.5安装的docker,而docker需要内核3.0以上的支持,所以必须升级内核 1. 导入public key rpm --import https://www.elrepo ...