Spring in Action 4 读书笔记之使用标签创建 AOP
目录
- 1. 定义一个 aspect
- 2. 创建一个 around advice
在之前的读书笔记 Spring in Acton 4 读书笔记之 AOP 原理及 Spring 对 AOP 的支持 中,讲到 Spring 对 AOP 的支持包含四方面:
- Spring 基于代理的经典的 AOP
- 使用 XML 配置将纯 POJO 转化为 aspect
- 使用 Spring 的 @Aspect 标签,创建 aspect
- Spring 不创建 aspect,只注入(引用)AspectJ 框架的 aspect
Spring in Action(Spring 实战)的第四章第三节(4.3 Creating annotated aspects)讲述了其中第三种,即如何使用标签创建 aspect。本文讲解其中的前面两小节:定义 aspect 以及创建 around advice。
AspectJ 5 引进的主要特性是使用标签创建 aspect。AspectJ 5 的缺点是需要学习扩展的 java 语言。但是 AspectJ 面向标签的编程模式使得将一个类转换成 aspect 变得很容易,只需要在类中加一些标签。
定义一个 aspect
以下是使用标签创建 AOP 的例子,这个例子在之前的文章中有提到过,观众在演出开始前后,以及出问题时,会自动做出一些反应:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 |
package concert; import org.aspectj.lang.annotation.AfterReturning; import org.aspectj.lang.annotation.AfterThrowing; import org.aspectj.lang.annotation.Aspect; import org.aspectj.lang.annotation.Before; @Aspect public class Audience { @Before("execution(** concert.Performance.perform(..))") public void silenceCellPhones() { System.out.println("Silencing cell phones"); } @Before("execution(** concert.Performance.perform(..))") public void takeSeats() { System.out.println("Taking seats"); } @AfterReturning("execution(** concert.Performance.perform(..))") public void applause() {  System.out.println("CLAP CLAP CLAP!!!"); } @AfterThrowing("execution(** concert.Performance.perform(..))") public void demandRefund() { System.out.println("Demanding a refund"); } } |
Audience 类上加上 @Aspect,用来表示 Audience 是一个 aspect,而 Audience 被标注的方法定义了具体的行为。在表演开始前,观众需要就座(takeSeats()),将手机静音(silenceCellPhones())。
表演结束后,观众需要鼓掌(applause()),如果表演过程中出现了异常,观众会要求退票(demandRefund())。AspectJ 提供了五个标签来定义 advice:
- @After,在方法正常执行结束,或者出现异常的时候,执行 aspect。
- @AfterReturning,在方法正常执行结束后,执行 aspect。
- @AfterThrowing,在方法抛出异常的时候,执行 aspect。
- @Around,在方法执行过程中,执行 aspect。
- @Before, 在方法执行之前,执行 aspect。
上面的例子中,所有标签的值都是一个 pointcut 表达式,而且在这个例子里,正好是一样的(因为是作用在同一个方法上)。实际上,可以将这个 pointcut 定义好,然后进行引用,这样可以避免重复编写 pointcut。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
@Aspect public class Audience { @Pointcut("execution(** concert.Performance.perform(..))") public void performance() {}  @Before("performance()") public void silenceCellPhones() { System.out.println("Silencing cell phones"); } @Before("performance()") public void takeSeats() { System.out.println("Taking seats"); } @AfterReturning("performance()") public void applause() { System.out.println("CLAP CLAP CLAP!!!"); } @AfterThrowing("performance()") public void demandRefund() { System.out.println("Demanding a refund"); } } |
上面的代码,使用 @Pointcut 标签对 performance()方法进行标注,这样,就可以直接使用 performance()来代替 pointcut 表达式了。performance()只是一个标记,所以方法体可以也必须是空的。
如果只是定义了上面 Audience 这个 aspect, 那么其实什么也做不了。必须有一个配置文件,指出它是一个 aspect,并且解析这些标签,然后创建代理,最终将 Audience 转化为一个 aspect。
如果是使用 JavaConfig, 可以在配置文件类加上 @EnableAspectJAutoProxy 标签,以实现自动代理。以下是示例:
1 2 3 4 5 6 7 8 9 |
@Configuration @EnableAspectJAutoProxy @ComponentScan public class ConcertConfig { @Bean public Audience audience() { return new Audience(); } } |
Spring 使用 AspectJ 进行自动代理,仅仅是使用 @AspectJ 的标签作为指引,而底层仍然是 Spring 自己的基于代理的 aspect。所以,尽管使用了 @AspectJ 标签,Spring 的 AOP 仍然只能作用在方法级别。如果要使用 AspectJ 的全部功能,就必须在运行时注入 AspectJ,而不使用 Spring 来创建基于代理的 aspect。
创建一个 around advice
前面讲解了 before 和 after 的用法,由于 around 的用法有些不同,也更有用,所以这里单讲。先看看下面的例子:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
@Aspect public class Audience { @Pointcut("execution(** concert.Performance.perform(..))") public void performance() {} @Around("performance()") public void watchPerformance(ProceedingJoinPoint jp) { try { System.out.println("Silencing cell phones"); System.out.println("Taking seats"); jp.proceed(); System.out.println("CLAP CLAP CLAP!!!"); } catch (Throwable e) { System.out.println("Demanding a refund"); } } } |
使用 @Around 标签标注了 watchPerformance 方法,监听 performance()代表的 joinpoint。此时,watchPerformance 的参数 ProceedingJoinPoint 就是指这个 joinpoint。可以看到,在 jp.proceed()的前后各有一些操作,甚至在抛出异常时,也有一些处理。所以,这个方法同时实现 @Before、@AfterReturning 和 @AfterThrowing 等标签的功能,更加灵活。
需要注意的是,必须执行 joinpoint 的 proceed()方法,否则,会导致被监听的方法没有执行。
我计划完成 50 到 100 篇关于 Spring 的文章,这是第十一篇,欢迎订阅 tantanit.com,第一时间获取文章更新,本文链接地址:http://tantanit.com/springinaction4-du-shu-bi-ji-zhi-shi-yong-biao-qian-chuang-jian-aop/
谈谈 IT的文章均为原创或翻译(翻译会注明外文来源),转载请以链接形式标明本文地址: http://tantanit.com/springinaction4-du-shu-bi-ji-zhi-shi-yong-biao-qian-chuang-jian-aop/
from: http://tantanit.com/springinaction4-du-shu-bi-ji-zhi-shi-yong-biao-qian-chuang-jian-aop/
Spring in Action 4 读书笔记之使用标签创建 AOP相关推荐
- 《ASP.NET Core In Action》读书笔记系列五 ASP.NET Core 解决方案结构解析1
<ASP.NET Core In Action>读书笔记系列五 ASP.NET Core 解决方案结构解析1 参考文章: (1)<ASP.NET Core In Action> ...
- JavaScript设计模式读书笔记(一)= 创建型设计模式
全系列目录 JavaScript设计模式读书笔记(一)=> 创建型设计模式 JavaScript设计模式读书笔记(二)=> 结构型设计模式 JavaScript设计模式读书笔记(三)=&g ...
- Spring in Action 4th 学习笔记 之 AOP
前提:本文中的AOP仅限于Spring AOP. 先说说为什么需要AOP 最简单的一个例子就是日志记录,如果想记录一些方法的执行情况,最笨的办法就是修改每一个需要记录的方法.但这,真的很笨... 好的 ...
- 《JavaEE框架整合开发入门到实战——Spring+SpringMVC+MyBatis》读书笔记
加油生活,嗯,希望假期可以把这本书刷完,新年快乐,嘻嘻,今天是旧的一年里最后的一天,嗯,除夕一过,就25岁啦.希望新的一年里,学更多的东西,认识优秀的人,希望家人健康平安,希望自己少一些烦恼,总之先学 ...
- spring boot 503_Spring实战读书笔记第4章 面向切面的Spring
本章内容: 面向切面编程的基本原理 通过POJO创建切面 使用@AspectJ注解 为AspectJ切面注入依赖 在软件开发中,散布于应用中多的功能被称为横切关注点(cross-cutting con ...
- 《Redis in action》读书笔记
为什么80%的码农都做不了架构师?>>> https://www.gitbook.io/book/abcfy2/redis-in-action-reading-notes 最近 ...
- 《Spring Boot实战》读书笔记
2019独角兽企业重金招聘Python工程师标准>>> 一. 读后感 Spring Boot在技术圈火了好多年了,直到最近才去系统学习它,真是相见恨晚.当我在IDE编写几行代码就把W ...
- Spring Cloud Gateway 概述 《重新定义Spring Cloud实战》读书笔记
什么是Spring Cloud Gateway Spring Cloud Gateway 是 Spring 官方基于 Spring 5.0.Spring Boot 2.0 和 Project Reac ...
- 《Java EE 开发的颠覆者:Spring Boot实战》读书笔记
第一章 Spring基础 Spring发展阶段 xml配置 注解配置(应用的基本配置,如数据库配置采用xml文件,业务配置有注解) java配置 每一个被Spring管理的java对象都称之为bean ...
最新文章
- JAVA基础10-继承(1)
- Octavia 的 HTTPS 与自建、签发 CA 证书
- Image Cloud Gallery
- Android异步加载
- 【数据分析】Python数据分析学习路线个人总结
- Linux上安装集群版Redis
- Idea和使用git命令上传本地新项目到gitee上
- 正则只能输入数字java_正则表达式限制输入字符,数字,汉字等
- 【小技巧】程序运行结束后弹窗提醒
- 鸿蒙系统是否兼容,鸿蒙系统能不能兼容windows的所有应用软件?
- 混沌matlab仿真
- 微分中的dx和delta x
- android 北斗测试,安卓手机查看是否支持北斗导航系统的详细检测方法
- UIPATH 调用SAP BAPI
- 【CF819C】Mister B and Beacons on Field 数学
- ACP 云计算试题集
- man 命令显示简体中文帮助
- 华为云配置https访问
- 5G消息(RCS),到底是什么?
- 密码打马赛克已经不安全了!这款开源的去“马赛克“工具一秒还原
热门文章
- 【复杂网络】图模型在欺诈检测应用一点看法
- 【行业报告】中国金融科技2017专题研究报告——易观智库
- DALSA线阵CCD相机开发 之 opencv读取图片
- 深度拆解:直播带货的现状与未来?
- 信息革命的新世界正在到来,连睡觉都觉得浪费
- 每日一博 - Spring Boot Application as a Service
- 白话Elasticsearch48-深入聚合数据分析之 Percentiles Aggregation-percentiles百分比算法以及网站访问时延统计及Percentiles优化
- 计算机视觉——利用openCV与Socket结合进行远程摄像头实时视频传输并保存图片数据
- c 输出空格_Python编程:案例详解输出函数print
- 安卓使用Span富文本给某段Text文本加上波浪线