Spring5(七)——AOP注解
一、AOP注解
1、介绍
上一节介绍了 AspectJ 框架如何实现 AOP,具体的实现方式是通过 xml 来进行配置的。xml 方式思路清晰,便于理解,但是书写过于麻烦。这一节介绍注解的方式来进行 AOP 配置。
2、案例(注解)
定义目标对象(被代理的对象)
1 // 定义一个接口
2 public interface ITeacher {
3 void teach();
4 int add(int i, int j);
5 }
6
7 // 定义目标对象
8 @Service
9 public class Teacher implements ITeacher {
10 @Override
11 public void teach() {
12 System.out.println("老师正在上课");
13 }
14
15 @Override
16 public int add(int i, int j) {
17 int add = i + j;
18 System.out.println("执行目标方法:老师正在做加法,结果为:" + add);
19 // int throwable = 10 / 0; 测试异常通知
20 return add;
21 }
22
23 // 目标对象自己的方法,此方法不是接口所以无法代理
24 public void sayHello() {
25 System.out.println("老师会说hello");
26 }
27
28 }
编写一个切面类(通知)
1 // 创建切面类(包含各种通知)
2 @Component
3 @Aspect
4 public class MyAspect {
5
6 // 1.先定义切入点表达式
7 @Pointcut("execution(* com.lx.spring.day4.ITeacher.*(..))")
8 private void myPointcut() {
9
10 }
11
12 // 2.标识此方法为一个前置通知,用来切满足后面切点表达式的方法
13 @Before("myPointcut()")
14 public void myBefore(JoinPoint joinPoint) {
15 System.out.println("前置通知:方法增强myBefore()" + " , -->" + joinPoint.getSignature().getName());
16 }
17
18 @AfterReturning(value = "myPointcut()", returning = "object")
19 public void myAfterReturning(JoinPoint joinPoint, Object object) {
20 System.out.println("后置通知:方法增强myAfterReturning()" + " , -->" + joinPoint.getSignature().getName() + " , -->" + object);
21 }
22
23 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
24 System.out.println("============环绕前==============");
25 Object obj = joinPoint.proceed(); // 手动执行目标方法
26 System.out.println("============环绕后==============");
27 return obj;
28 }
29
30 public void myAfterThrowing(JoinPoint joinPoint, Throwable e) {
31 System.out.println("抛出异常通知:" + e.getMessage());
32 }
33
34 public void myAfter() {
35 System.out.println("最终通知:方法增强myAfter()");
36 }
37
38 }
编写配置文件 application.xml
1 <!-- 1.自动扫描(自动注入bean) -->
2 <context:component-scan base-package="com.lx.spring.day4"/>
3
4 <!-- 2.扫描 @Aspect 告诉 spring 这是一个切面类 -->
5 <aop:aspectj-autoproxy/>
1 // 测试类
2 public class Main {
3 public static void main(String[] args) {
4 ApplicationContext app = new ClassPathXmlApplicationContext("app4.xml");
5 ITeacher iTeacher = app.getBean(ITeacher.class);
6
7 iTeacher.add(11, 24);
8 }
9 }
10
11 // 结果
12 前置通知:方法增强myBefore() , -->add
13 执行目标方法:老师正在做加法,结果为:35
14 后置通知:方法增强myAfterReturning() , -->add , -->35
说明:对比 xml 的配置,不难理解注解的方式。
@Service @Component
<context:component-scan base-package="com.lx.spring.day4"/>
用于 Spring 扫描并注册bean。
@Aspect:指明这是一个切面类
<aop:aspectj-autoproxy/>:开启切面注解扫描
3、优先级
有多个增强类对同一个方法进行增强,设置增强类优先级,在增强类上面添加注解 @Order(数字类型值),数字类型值越小优先级越高。
1 @Component
2 @Aspect
3 @Order(1)
4 public class MyAspect2 {}
优先级:这里的优先级,只会影响两个增强类对应的方法,执行的先后顺序。并不会只执行优先级高的。
二、AOP+自定义注解
通过AOP+自定义注解的方式,可以实现前面说的抽取公共非业务模块,对业务逻辑的增强。比如:
需求:①想要对业务逻辑层的所有方法,打印出入参和出参,做日志管理。②对业务逻辑层的方法入口,开启事务,逻辑执行后,提交事务,等。

自定义注解
1 // 用于日志打印
2 @Target({ElementType.METHOD})
3 @Retention(RetentionPolicy.RUNTIME)
4 @Documented
5 public @interface Log {
6
7 String value() default "";
8 }
1 @Component
2 @Aspect
3 public class MyAspect {
4
5 // 定义切入点为 有注解Log的方法
6 @Pointcut("@annotation(com.lx.spring.day5.Log) ")
7 private void myLogPointcut() {
8
9 }
10
11 // 为切入点增强一个环绕通知,可以在这里写打印入参出参的逻辑
12 @Around("myLogPointcut()")
13 public Object myAround(ProceedingJoinPoint joinPoint) throws Throwable {
14 System.out.println("============环绕前==============");
15 Object obj = joinPoint.proceed(); // 手动执行目标方法
16 System.out.println("============环绕后==============");
17 return obj;
18 }
19
20 }
1 @Service
2 public class Teacher implements ITeacher {
3
4 // 为需要打印入参出参的方法 加上@Log注解即可
5 @Log
6 @Override
7 public int add(int i, int j) {
8 int add = i + j;
9 System.out.println("执行目标方法:老师正在做加法,结果为:" + add);
10 // int throwable = 10 / 0; 测试异常通知
11 return add;
12 }
13
14 }
1 public class Main {
2 public static void main(String[] args) {
3 ApplicationContext app = new ClassPathXmlApplicationContext("app4.xml");
4 ITeacher iTeacher = app.getBean(ITeacher.class);
5
6 iTeacher.add(11, 24);
7 }
8 }
9
10 // 结果
11 ============环绕前==============
12 执行目标方法:老师正在做加法,结果为:35
13 ============环绕后==============
Spring5(七)——AOP注解的更多相关文章
- Spring详解(七)------AOP 注解
上一篇博客我们讲解了 AspectJ 框架如何实现 AOP,然后具体的实现方式我们是通过 xml 来进行配置的.xml 方式思路清晰,便于理解,但是书写过于麻烦.这篇博客我们将用 注解 的方式来进行 ...
- 来一手 AOP 注解方式进行日志记录
系统日志对于定位/排查问题的重要性不言而喻,相信许多开发和运维都深有体会. 通过日志追踪代码运行状况,模拟系统执行情况,并迅速定位代码/部署环境问题. 系统日志同样也是数据统计/建模的重要依据,通过分 ...
- Spring详解(六)------AOP 注解
上一篇博客我们讲解了 AspectJ 框架如何实现 AOP,然后具体的实现方式我们是通过 xml 来进行配置的.xml 方式思路清晰,便于理解,但是书写过于麻烦.这篇博客我们将用 注解 的方式来进行 ...
- SpringBoot —— AOP注解式拦截与方法规则拦截
AspectJ是一个面向切面的框架,它扩展了Java语言.AspectJ定义了AOP语法,所以它有一个专门的编译器用来生成遵守Java字节编码规范的Class文件. SpringBoot中AOP的使用 ...
- Spring AOP注解为什么失效?90%Java程序员不知道
使用Spring Aop注解的时候,如@Transactional, @Cacheable等注解一般需要在类方法第一个入口的地方加,不然不会生效. 如下面几种场景 1.Controller直接调用Se ...
- Spring入门(三)— AOP注解、jdbc模板、事务
一.AOP注解开发 导入jar包 aop联盟包. aspectJ实现包 . spring-aop-xxx.jar . spring-aspect-xxx.jar 导入约束 aop约束 托管扩展类和被扩 ...
- SpringBoot整合Mybatis多数据源 (AOP+注解)
SpringBoot整合Mybatis多数据源 (AOP+注解) 1.pom.xml文件(开发用的JDK 10) <?xml version="1.0" encoding=& ...
- Spring AOP注解形式简单实现
实现步骤: 1:导入类扫描的注解解析器 命名空间:xmlns:context="http://www.springframework.org/schema/context" xsi ...
- AOP注解不起作用的debug结果
经过2天的调试,我发现AOP注解配置不起作用居然是表达式的错误导致的 在xml文件中配置的base-package有关,初步认为@PointCut只能使用base-package..*(..)这样的方 ...
随机推荐
- Crash course statistics
Crash course statistics 01什么是统计学 描述性统计(Descriptive statistics) 推理统计可以得出之外的,基于"样本"的推论统计学来估计 ...
- nagios介绍和安装
官方support文献: https://support.nagios.com/kb/ 1.Nagios的监控模式: 主动式检查:NCPA.NRPE nagios安装后默认使用主动检查方式,远程执行代 ...
- USB 3.0 开发要点
最近在公司里安排了我一个新的任务,那就是USB3.0的研发.对于我之前都是做ARM+LINUX和单片机软件研发的来说,虽然之前都是做驱动程序和应用程序,但是没有做与USB 相关的开发,毕竟这是第一次. ...
- 基于ivy的源代码调试方法
项目PORJ_TEST是项目PROJ的测试项目.在它的ivy中引用了PROJ的jar包.由于PROJ正处于开发阶段,源代码更改频繁, 在运行PROJ_TEST中的测试时,需要进入PROJ的jar包内部 ...
- 记客户端出现Connect reset问题排查。
客户访问我们地址出现Connect reset. 网上查询说是服务端关闭,客户端还在读,就会出现Connect reset. 我们就排查为什么服务端会关闭. 网络的同事说收到了客户端的信息,但是被服务 ...
- Shell-02-数据类型
shell数据类型 shell常用的数据类型有 字符串.整数型.数组 字符串 字符串是shell编程中最常用最有用的数据类型,字符串可以用单引号,也可以用双引号,也可以不用引号 建议使用双引号,因为双 ...
- 【原创】Spring Data Redis <=2.0.3反序列化漏洞
Spring Data Redis隶属于Spring Data家族, 提供简单易用的方式来访问Redis缓存. Spring Data Redis在往Redis里面写数据的时候,默认会先对数据进行序列 ...
- ☕【Java技术指南】「并发原理专题」AQS的技术体系之CLH、MCS锁的原理及实现
背景 SMP(Symmetric Multi-Processor) 对称多处理器结构,它是相对非对称多处理技术而言的.应用十分广泛的并行技术. 在这种架构中,一台计算机由多个CPU组成,并共享内存和其 ...
- linux下安装redis-6.0.6、配置redis远程连接
官网下载安装包redis-6.0.6.tar.gz https://redis.io/ 上传到服务器之后使用tar -zxvf进行解压,解压后如下: 进入解压的文件之后我们可以看到他的配置文件(配置文 ...
- Android 9.0 默认输入法的设置流程分析
Android 输入法设置文章 Android 9.0 默认输入法的设置流程分析 Android 9.0 添加预置第三方输入法/设置默认输入法(软键盘) 前言 在上一篇文章 Android 9.0 ...