源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all

一、说明

1.1 项目结构说明

切面配置位于resources下的aop.xml文件,其中CustomAdvice是自定义切面类,OrderService是待切入的方法。

1.2 依赖说明

除了spring的基本依赖外,需要导入aop依赖包

  1. <!--aop 相关依赖-->
  2. <dependency>
  3. <groupId>org.springframework</groupId>
  4. <artifactId>spring-aop</artifactId>
  5. <version>${spring-base-version}</version>
  6. </dependency>

二、spring aop

2.1 创建待切入接口及其实现类

  1. public interface OrderService {
  2. Order queryOrder(Long id);
  3. Order createOrder(Long id, String productName);
  4. }
  1. public class OrderServiceImpl implements OrderService {
  2. public Order queryOrder(Long id) {
  3. return new Order(id, "product", new Date());
  4. }
  5. public Order createOrder(Long id, String productName) {
  6. // 模拟抛出异常
  7. // int j = 1 / 0;
  8. return new Order(id, "new Product", new Date());
  9. }
  10. }

2.2 创建自定义切面类

  1. /**
  2. * @author : heibaiying
  3. * @description : 自定义切面
  4. */
  5. public class CustomAdvice {
  6. //前置通知
  7. public void before(JoinPoint joinPoint) {
  8. //获取节点名称
  9. String name = joinPoint.getSignature().getName();
  10. Object[] args = joinPoint.getArgs();
  11. System.out.println(name + "方法调用前:获取调用参数" + Arrays.toString(args));
  12. }
  13. //后置通知(抛出异常后不会被执行)
  14. public void afterReturning(JoinPoint joinPoint, Object result) {
  15. System.out.println("后置返回通知结果" + result);
  16. }
  17. //环绕通知
  18. public Object around(ProceedingJoinPoint joinPoint) throws Throwable {
  19. System.out.println("环绕通知-前");
  20. //调用目标方法
  21. Object proceed = joinPoint.proceed();
  22. System.out.println("环绕通知-后");
  23. return proceed;
  24. }
  25. //异常通知
  26. public void afterException(JoinPoint joinPoint, Exception exception) {
  27. System.err.println("后置异常通知:" + exception);
  28. }
  29. ;
  30. // 后置通知 总会执行 但是不能访问到返回值
  31. public void after(JoinPoint joinPoint) {
  32. System.out.println("后置通知");
  33. }
  34. }

2.3 配置切面

  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <beans xmlns="http://www.springframework.org/schema/beans"
  3. xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  4. xmlns:aop="http://www.springframework.org/schema/aop"
  5. xsi:schemaLocation="http://www.springframework.org/schema/beans
  6. http://www.springframework.org/schema/beans/spring-beans.xsd
  7. http://www.springframework.org/schema/aop
  8. http://www.springframework.org/schema/aop/spring-aop.xsd">
  9. <!--开启后允许使用Spring AOP的@AspectJ注解 如果是纯xml配置 可以不用开启这个声明-->
  10. <aop:aspectj-autoproxy/>
  11. <!-- 1.配置目标对象 -->
  12. <bean name="orderService" class="com.heibaiying.service.OrderServiceImpl"/>
  13. <!-- 2.声明切面 -->
  14. <bean name="myAdvice" class="com.heibaiying.advice.CustomAdvice"/>
  15. <!-- 3.配置将通知织入目标对象 -->
  16. <aop:config>
  17. <!--命名切入点 关于切入点更多表达式写法可以参见README.md-->
  18. <aop:pointcut expression="execution(* com.heibaiying.service.OrderService.*(..))" id="cutPoint"/>
  19. <aop:aspect ref="myAdvice">
  20. <!-- 前置通知 -->
  21. <aop:before method="before" pointcut-ref="cutPoint"/>
  22. <!-- 后置通知 如果需要拿到返回值 则要指明返回值对应的参数名称-->
  23. <aop:after-returning method="afterReturning" pointcut-ref="cutPoint" returning="result"/>
  24. <!-- 环绕通知 -->
  25. <aop:around method="around" pointcut-ref="cutPoint"/>
  26. <!-- 后置异常 如果需要拿到异常 则要指明异常对应的参数名称 -->
  27. <aop:after-throwing method="afterException" pointcut-ref="cutPoint" throwing="exception"/>
  28. <!-- 最终通知 -->
  29. <aop:after method="after" pointcut-ref="cutPoint"/>
  30. </aop:aspect>
  31. </aop:config>
  32. </beans>

2.4 测试切面

  1. @RunWith(SpringRunner.class)
  2. @ContextConfiguration("classpath:aop.xml")
  3. public class AopTest {
  4. @Autowired
  5. private OrderService orderService;
  6. @Test
  7. public void save() {
  8. orderService.createOrder(1283929319L, "手机");
  9. orderService.queryOrder(4891894129L);
  10. }
  11. }

附: 关于切面表达式的说明

切面表达式遵循以下格式:

  1. execution(modifiers-pattern? ret-type-pattern declaring-type-pattern?name-pattern(param-pattern)
  2. throws-pattern?)
  • 除了返回类型模式,名字模式和参数模式以外,所有的部分都是可选的;
  • *,它代表了匹配任意的返回类型;
  • () 匹配了一个不接受任何参数的方法, 而 (..) 匹配了一个接受任意数量参数的方法(零或者更多)。 模式 (*) 匹配了一个接受一个任何类型的参数的方法。 模式 (*,String) 匹配了一个接受两个参数的方法,第一个可以是任意类型,第二个则必须是String类型。

下面给出一些常见切入点表达式的例子。

  • 任意公共方法的执行:

    1. execution(public * *(..))
  • 任何一个以“set”开始的方法的执行:

    1. execution(* set*(..))
  • AccountService 接口的任意方法的执行:

    1. execution(* com.xyz.service.AccountService.*(..))
  • 定义在service包里的任意方法的执行:

    1. execution(* com.xyz.service.*.*(..))
  • 定义在service包或者子包里的任意方法的执行:

    1. execution(* com.xyz.service..*.*(..))
  • 在service包里的任意连接点(在Spring AOP中只是方法执行) :

    1. within(com.xyz.service.*)
  • 在service包或者子包里的任意连接点(在Spring AOP中只是方法执行) :

    1. within(com.xyz.service..*)
  • 实现了 AccountService 接口的代理对象的任意连接点(在Spring AOP中只是方法执行) :

    1. this(com.xyz.service.AccountService)

更多表达式可以参考官方文档:Declaring a Pointcut

附:源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all

spring 5.x 系列第3篇 —— spring AOP (xml配置方式)的更多相关文章

  1. spring 5.x 系列第1篇 —— springmvc基础 (xml配置方式)

    文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关配置讲解 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...

  2. spring 5.x 系列第17篇 —— 整合websocket (xml配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 项目模拟一个简单的群聊功能,为区分不同的聊 ...

  3. spring 5.x 系列第15篇 —— 整合dubbo (xml配置方式)

    文章目录 一. 项目结构说明 二.项目依赖 三.公共模块(dubbo-common) 四. 服务提供者(dubbo-provider) 4.1 productService是服务的提供者( 商品数据用 ...

  4. spring 5.x 系列第13篇 —— 整合RabbitMQ (xml配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 本用例关于rabbitmq的整合提供简单消 ...

  5. spring 5.x 系列第11篇 —— 整合memcached (xml配置方式)

    文章目录 一.说明 1.1 XMemcached客户端说明 1.2 项目结构说明 1.3 依赖说明 二.spring 整合 memcached 2.1 单机配置 2.2 集群配置 2.3 存储基本类型 ...

  6. spring 5.x 系列第9篇 —— 整合mongodb (xml配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 配置文件位于resources下,项目以单 ...

  7. spring 5.x 系列第2篇 —— springmvc基础 (代码配置方式)

    文章目录 一.搭建hello spring工程 1.1 项目搭建 1.2 相关注解说明 二.配置自定义拦截器 三.全局异常处理 四.参数绑定 4.1 参数绑定 4.2 关于日期格式转换的三种方法 五. ...

  8. spring 5.x 系列第18篇 —— 整合websocket (代码配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 项目模拟一个简单的群聊功能,为区分不同的聊 ...

  9. spring 5.x 系列第16篇 —— 整合dubbo (代码配置方式)

    文章目录 一. 项目结构说明 二.项目依赖 三.公共模块(dubbo-ano-common) 四. 服务提供者(dubbo-ano-provider) 4.1 提供方配置 4.2 使用注解@Servi ...

  10. spring 5.x 系列第14篇 —— 整合RabbitMQ (代码配置方式)

    源码Gitub地址:https://github.com/heibaiying/spring-samples-for-all 一.说明 1.1 项目结构说明 本用例关于rabbitmq的整合提供简单消 ...

随机推荐

  1. 一个Java工程师的入门级Linux命令集

    0.前言    网上介绍linux的命令的文章一大堆,但是大部分都是流于命令介绍,把命令的所有参数都介绍一遍,但是其实在真正的工作中,很多参数都不会用到.本文总结了我自己常用的一些命令,这些命令都比较 ...

  2. HDU1728 从迷宫中逃脱 【方向BFS】

    从迷宫中逃脱 Time Limit: 1000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Sub ...

  3. 《Planet Earth II》观看笔记

    carrion:n. 腐肉:臭尸:不洁之物 cub:n. 幼兽:不懂规矩的年轻人:chick; n. 小鸡:小鸟:少妇 herd:兽群: 1. 高频单词 terrain:n. [地理] 地形,地势:领 ...

  4. Python 函数调用性能记录

    之前用 JS 写项目的时候,项目组用的组件模式,一直感觉很不错.最近用 Python 做新项目,项目结构也延续了组件模式.一直没有对函数调用的性能作了解,今天突发奇想测试了一下,写了一些测试代码 首先 ...

  5. 《Linux Device Drivers》第十一章 核心数据类型——note

    基本介绍 因为Linux多平台特性,不管是哪一个重要驱动力应该是便携 与内核代码相关的核心问题应该是访问的同时是数据项的已知长度.能力和利用不同的处理器 内核使用的数据类型主要分为三类 类似int这种 ...

  6. [转载]Delphi常用类型及定义单元

    原文地址:Delphi常用类型及定义单元作者:沧海一声笑 Delphi常用类型及定义单元-总结  sndplaysound                mmsystem Type Unit Date ...

  7. WPF实现选项卡效果(2)——动态添加AvalonDock选项卡

    原文:WPF实现选项卡效果(2)--动态添加AvalonDock选项卡 简介 在前面一篇文章里面,我们使用AvalonDock实现了类似于VS的选项卡(或者浏览器的选项卡)效果.但是我们是通过xaml ...

  8. XF 列表视图绑定集合

    using System;using System.Collections.Generic;using System.Linq;using System.Text;using System.Threa ...

  9. QT 窗体控件的透明度设置(三种方法)

    整个窗体 当设置QT的窗体(QMainWindow, QDialog)时,直接用 targetForm->setWindowOpacity()   函数即可实现,效果为窗体及窗体内所有控件都透明 ...

  10. MVC CRUD 的两种方法

    //Index.cshtml @model IQueryable<MvcExam2.Models.Product>@{    Layout = null;}<!DOCTYPE htm ...