范例:定义一个参数拦截

  1. package com.Spring.aop;
  2.  
  3. import org.springframework.stereotype.Component;
  4.  
  5. @Component
  6. public class ServiceAspect {
  7.  
  8. public void serviceBefore()
  9. {
  10. System.out.println("AOP切面执行日志记录操作");
  11. }
  12.  
  13. public void serviceBefore2(Object arg)
  14. {
  15. System.out.println("AOP切面执行增加前操作,参数="+arg);
  16. }
  17. public void serviceAfter()
  18. {
  19. System.out.println("AOP切面执行事务处理操作");
  20. }
  21. }

配置也修改:

  1. <aop:config>
  2. <!-- 定义程序的切入点 -->
  3. <aop:pointcut expression="execution(* com.Spring..*.*(..)))" id="pointcut"/>
  4. <!-- 这里ref的对象是通过annotation配置@Component出来的, -->
  5. <!-- 定义面向方面的处理类 -->
  6. <aop:aspect ref="serviceAspect">
  7. <aop:before method="serviceBefore2" pointcut-ref="pointcut"/>
  8. <aop:after method="serviceAfter" pointcut-ref="pointcut"/>
  9. </aop:aspect>
  10. </aop:config>
  11. <aop:aspectj-autoproxy proxy-target-class="true"/>

此时运行报错。

此时serviceBefore2方法有参数了,就需要修改了。

范例:定义切入点表达式

这里通过 and args()  和arg-names来指定要传入操作前方法的参数。

  1. <aop:config>
  2. <!-- 定义程序的切入点 -->
  3. <aop:pointcut expression="execution(* com.Spring..*.*(..)) and args(vo))" id="pointcut"/>
  4. <!-- 这里ref的对象是通过annotation配置@Component出来的, -->
  5. <!-- 定义面向方面的处理类 -->
  6. <aop:aspect ref="serviceAspect">
  7. <aop:before method="serviceBefore2" pointcut-ref="pointcut" arg-names="vo"/>
  8. <aop:after method="serviceAfter" pointcut="execution(* com.Spring..*.*(..)))"/>
  9. </aop:aspect>
  10. </aop:config>
  11. <aop:aspectj-autoproxy proxy-target-class="true"/>

运行结果:

因为after方法没有参数,不能直接使用第一个定义的切入点,所以这里after方法重新指定一个切入点,

而before是有参数的,直接使用第一个定义的切入点就行了。

除了操作之前拦截,也可以针对返回的结果进行拦截。

范例:针对返回结果拦截

  1. package com.Spring.aop;
  2.  
  3. import org.springframework.stereotype.Component;
  4.  
  5. @Component
  6. public class ServiceAspect {
  7.  
  8. public void serviceBefore()
  9. {
  10. System.out.println("AOP切面执行日志记录操作");
  11. }
  12.  
  13. public void serviceBefore2(Object arg)
  14. {
  15. System.out.println("AOP切面执行增加前操作,参数=" +arg);
  16. }
  17. public void serviceAfter()
  18. {
  19. System.out.println("AOP切面执行事务处理操作");
  20. }
  21. public void serviceAfterReturn(Object val) //表示操作结果
  22. {
  23. System.out.println("AOP切面操作完成,返回结果:"+val);
  24. }
  25. }

配置里面修改:

  1. <aop:config>
  2. <!-- 定义程序的切入点 -->
  3. <aop:pointcut expression="execution(* com.Spring..*.*(..)) and args(vo))" id="pointcut"/>
  4. <!-- 这里ref的对象是通过annotation配置@Component出来的, -->
  5. <!-- 定义面向方面的处理类 -->
  6. <aop:aspect ref="serviceAspect">
  7. <aop:before method="serviceBefore2" pointcut-ref="pointcut" arg-names="vo"/>
  8. <aop:after method="serviceAfter" pointcut="execution(* com.Spring..*.*(..)))"/>
  9. <aop:after-returning method="serviceAfterReturn" pointcut="execution(* com.Spring..*.*(..)))" returning="haha" arg-names="haha"/>
  10. </aop:aspect>
  11. </aop:config>

这里通过returning和arg-names来传递返回结果给操作完成后返回方法:serviceAfterReturn,做完这个方法的参数。

执行结果:

除了返回结果的拦截之外,还能进行异常处理的拦截操作。

范例:修改MemberServiceImpl

  1. package com.Spring.Test;
  2.  
  3. import org.apache.commons.lang.NullArgumentException;
  4. import org.springframework.context.ApplicationContext;
  5. import org.springframework.context.support.ClassPathXmlApplicationContext;
  6.  
  7. import com.Spring.Service.IMemberService;
  8. import com.Spring.Service.Impl.MemberServiceImpl;
  9. import com.Spring.Vo.Member;
  10.  
  11. public class TestMemberService {
  12.  
  13. public static void main(String args[])
  14. {
  15. throw new NullArgumentException("我来抛出一个异常");
  16. /*
  17. ApplicationContext ctx=new ClassPathXmlApplicationContext("applicationContext.xml");
  18. IMemberService ser=ctx.getBean("memberServiceImpl",MemberServiceImpl.class);
  19. Member vo=new Member();
  20. vo.setMid("hello");
  21. vo.setName("你好");
  22. System.out.println(ser.insert(vo));
  23. */
  24. }
  25. }

增加拦截处理操作

  1. package com.Spring.aop;
  2.  
  3. import org.springframework.stereotype.Component;
  4.  
  5. @Component
  6. public class ServiceAspect {
  7.  
  8. public void serviceBefore()
  9. {
  10. System.out.println("AOP切面执行日志记录操作");
  11. }
  12.  
  13. public void serviceBefore2(Object arg)
  14. {
  15. System.out.println("AOP切面执行增加前操作,参数=" +arg);
  16. }
  17. public void serviceAfter()
  18. {
  19. System.out.println("AOP切面执行事务处理操作");
  20. }
  21. public void serviceAfterReturn(Object val) //表示操作结果
  22. {
  23. System.out.println("AOP切面操作完成,返回结果:"+val);
  24. }
  25.  
  26. public void serviceAfterThrow(Exception e) //表示操作结果
  27. {
  28. System.out.println("AOP切面操作出现异常:"+e);
  29. }
  30. }

配置:

  1. <aop:config>
  2. <!-- 定义程序的切入点 -->
  3. <aop:pointcut expression="execution(* com.Spring..*.*(..)) and args(vo))" id="pointcut"/>
  4. <!-- 这里ref的对象是通过annotation配置@Component出来的, -->
  5. <!-- 定义面向方面的处理类 -->
  6. <aop:aspect ref="serviceAspect">
  7. <aop:before method="serviceBefore2" pointcut-ref="pointcut" arg-names="vo"/>
  8. <aop:after method="serviceAfter" pointcut="execution(* com.Spring..*.*(..)))"/>
  9. <aop:after-returning method="serviceAfterReturn" pointcut="execution(* com.Spring..*.*(..)))" returning="haha" arg-names="haha"/>
  10. <aop:after-throwing method="serviceAfterThrow" pointcut="execution(* com.Spring..*.*(..)))" arg-names="e" throwing="abc"/>
  11. </aop:aspect>
  12. </aop:config>
  13. <aop:aspectj-autoproxy proxy-target-class="true"/>

这里因为需要传递异常参数,所以需要arg-names和throwing,但是这两个的值随便写就像了,不用想对应起来。

运行结果:

以上几个拦截器已经可以处理AOP可以处理的范畴。但是为了简化,整个AOP还提供环绕通知,

即一个方法可以处理所有的aop操作,这种操作更像代理结构:

范例:增加环绕处理

但是必须考虑接收参数的情况,而接收的参数类型只能是一种类型:ProceedingJoinPoint,通过此类型可以取得全部的提交参数信息。

  1. public Object serviceAround(ProceedingJoinPoint point) throws Throwable
  2. {
  3. System.out.println("AOP切面数据层方法调用之前,参数:"+Arrays.toString(point.getArgs()));
  4. Member vo=new Member();
  5. vo.setMid("TestAOP");
  6. vo.setName("测试AOP");
  7. Object retVal=point.proceed(new Object[]{ vo });  //retVal接收方法数据层调用之后的结果
  8. System.out.println("AOP切面数据层方法调用之后,返回值:"+retVal);
  9. return true;
  10. }

在整个环绕拦截之中,用户可以任意修改传递的参数数据,也可以修改返回的结果。

配置环绕拦截:

  1. <aop:around method="serviceAround" pointcut="execution(* com.Spring..*.*(..)))" />

执行结果:

所以,在所有AOP操作中,环绕的功能是最强大的。其他拦截只能做一些信息记录,而环绕可以对传入的参数和返回结果进行控制。

18-spring学习-AOP深入操作的更多相关文章

  1. Spring Boot AOP 简易操作日志管理

    AOP (Aspect Oriented Programming) 面向切面编程. 业务有核心业务和边缘业务. 比如用户管理,菜单管理,权限管理,这些都属于核心业务. 比如日志管理,操作记录管理,这些 ...

  2. [原创]java WEB学习笔记107:Spring学习---AOP切面的优先级,重用切点表达式

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  3. [原创]java WEB学习笔记106:Spring学习---AOP的通知 :前置通知,后置通知,返回通知,异常通知,环绕通知

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  4. [原创]java WEB学习笔记105:Spring学习---AOP介绍,相关概念,使用AOP,利用 方法签名 编写 AspectJ 切入点表达式

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  5. [原创]java WEB学习笔记104:Spring学习---AOP 前奏,通过一个问题引入动态代理

    本博客的目的:①总结自己的学习过程,相当于学习笔记 ②将自己的经验分享给大家,相互学习,互相交流,不可商用 内容难免出现问题,欢迎指正,交流,探讨,可以留言,也可以通过以下方式联系. 本人互联网技术爱 ...

  6. spring 学习 AOP和IOC

    自11开始接触三大框架,至今已俞5载, 当时风光无限的ssh,现在还在被广泛使用,并有扩大之势的只有spring了 spring主要特性,是广为使用的AOP(面向切面)和IOC(控制反转) 1.其中, ...

  7. spring学习之三 数据库操作jdbcTemplate

    概念 jdbcTemplate就Spring对数据库持久化技术的实现,通过它可以对数据库进行CRUD等操作. JDBCTemplate和代码实现 public void jdbcadd() { Dri ...

  8. Spring学习-- AOP入门动态代理

    AOP 的拦截功能是由 java 中的动态代理来实现的.说白了,就是在目标类的基础上增加切面逻辑,生成增强的目标类(该切面逻辑或者在目标类函数执行之前,或者目标类函数执行之后,或者在目标类函数抛出异常 ...

  9. 黑马Spring学习 AOP XML和注解配置 5种通知 切点切面通知织入

    业务类 package cn.itcast.aop; import org.aspectj.lang.JoinPoint; import org.aspectj.lang.ProceedingJoin ...

随机推荐

  1. HDU 5301 Buildings 数学

    Buildings 题目连接: http://acm.hdu.edu.cn/showproblem.php?pid=5301 Description Your current task is to m ...

  2. 网络抓包工具wireshark常用封装过滤规则

    过滤器的区别 捕捉过滤器(CaptureFilters):用于决定将什么样的信息记录在捕捉结果中.需要在开始捕捉前设置.显示过滤器(DisplayFilters):在捕捉结果中进行详细查找.他们可以在 ...

  3. WPF ClickOnce应用程序IIS部署发布攻略

    WPF程序非常适合公司内网使用,唯一缺点就是客户端要安装.net框架4.0.优势也很明显,在客户端运行的是一个WinForm程序,自动下载,可以充分利用客户机的性能,而且是以当前的Windows用户权 ...

  4. ARMv7处理器各个模式之间是怎样切换的?模式切换时上下文的保存哪些是硬件在做?哪些是操作系统在做?

    1.ARM处理器各个模式之间是怎样切换的? 答:除用户模式外的其它6种模式称为特权模式,这些模式中,程序能够訪问全部系统资源,也能够随意进行处理器模式的切换.处理器模式能够通过软件控制进行切换(直接设 ...

  5. zend studio配置调试(Xdebug方式)

    1.下载xdebug http://xdebug.org/download.php 我下的是PHP 5.4 VC9 (32 bit) [当前系统php是php5.4.14(win32)版本] 2.配置 ...

  6. jquery点击回到页面顶部方法

    1.代码实例 <!DOCTYPE html> <html lang="en"> <head> <meta charset="UT ...

  7. 世界围棋人机大战、顶峰对决第一盘:围棋世界冠军Lee Sedol(李世石,围棋职业九段)对战Google DeepMind AlphaGo围棋程序

    Match 1 - Google DeepMind Challenge Match: Lee Sedol vs AlphaGo 很多网站对世界围棋大战进行了现场直播,比如YouTube.新浪.乐视.腾 ...

  8. [转]awk使用手册

    awk 手册 简体中文版由bones7456 (bones7456@gmail.com)整理. 原文:应该是 http://phi.sinica.edu.tw/aspac/reports/94/940 ...

  9. ZZY的宠物(矩阵运算+快速幂)

    E :ZZY的宠物 描述 ZZY领养了一对刚刚出生的不知名小宠物..巨萌巨可爱!!...小宠物的生命为5个单位时间并且不会在中间出意外翘辫子(如: 从0出生能活到5但活不到6)..小宠物经过2个单位时 ...

  10. 《java 语言程序设计》第1章编程练习

    1.1 public class test { public static void main(String[] args) { System.out.println("Welcome to ...