当前位置: 首页 > news >正文

[特殊字符] Spring AOP 注解方式详解

一、AOP 注解方式简介

学习了 Spring AOP 的 XML 配置方式
需要写很多 <aop:aspect><aop:before> 标签来配置切面。

但在实际开发中,这样写太麻烦了!
Spring 提供了更简洁的方式 —— 使用注解来实现 AOP

通过几个简单的注解,就能实现相同甚至更强大的功能。


二、AOP 注解方式的基本步骤

AOP 注解方式的实现步骤非常简单:

  1. 导入 AOP 相关依赖(和之前一样)

  2. 编写业务类(目标对象)

  3. 编写切面类,加上 @Aspect 和各种通知注解

  4. 在配置文件中开启注解代理 <aop:aspectj-autoproxy/>

  5. 编写测试类进行验证

是不是比 XML 清爽多了?😎


三、准备工作

1️⃣ Maven 依赖

与上一章完全相同,只要确保包含了这几个核心包:

<!-- Spring AOP 相关 -->
<dependency><groupId>org.springframework</groupId><artifactId>spring-aspects</artifactId><version>5.0.2.RELEASE</version>
</dependency><dependency><groupId>org.aspectj</groupId><artifactId>aspectjweaver</artifactId><version>1.8.3</version>
</dependency>

四、业务层代码

我们先写一个普通的业务类——订单业务类

OrderService.java

package com.qcbyjy.demo3;public interface OrderService {void save();
}

OrderServiceImpl.java

package com.qcbyjy.demo3;import org.springframework.stereotype.Service;@Service  // 把该类交给IOC容器管理
public class OrderServiceImpl implements OrderService {@Overridepublic void save() {System.out.println("业务层:保存订单...");}
}

五、编写切面类(使用注解声明切面)

MyAnnoAspect.java

package com.qcbyjy.demo3;import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Before;
import org.springframework.stereotype.Component;@Component      // 交给Spring容器管理
@Aspect         // 声明这是一个切面类(相当于 <aop:aspect>)
public class MyAnnoAspect {/*** 通知方法*/@Before(value = "execution(public * com.qcbyjy.demo3.OrderServiceImpl.save(..))")public void log() {System.out.println("【AOP增强】方法执行前:记录日志...");}
}

📘 解释一下:

  • @Aspect:声明当前类是一个切面。

  • @Before:声明一个前置通知。

  • execution(...):切入点表达式,表示拦截 OrderServiceImpl.save() 方法。


六、Spring 配置文件开启 AOP 支持

applicationContext_demo3.xml 中,添加一行关键配置:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xmlns:aop="http://www.springframework.org/schema/aop"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsd"><!-- 扫描包 --><context:component-scan base-package="com.qcbyjy.demo3"/><!-- 开启AOP注解代理 --><aop:aspectj-autoproxy/>
</beans>

这句 <aop:aspectj-autoproxy/> 就是关键,相当于告诉 Spring:

“去扫描那些带 @Aspect 的类,把它们织入到对应的目标方法中!”


七、编写测试类

Demo3.java

package com.qcbyjy.test;import com.qcbyjy.demo3.OrderService;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration("classpath:applicationContext_demo3.xml")
public class Demo3 {@Autowiredprivate OrderService orderService;@Testpublic void run1() {orderService.save();}
}

输出结果:

【AOP增强】方法执行前:记录日志...
业务层:保存订单...

完美!🎉
这说明我们的注解版 AOP 已经成功运行!


八、AOP 注解通知类型大全

Spring 支持五种常用的通知类型注解👇:

注解通知类型执行时机
@Before前置通知目标方法执行前
@AfterReturning后置通知方法成功执行后
@AfterThrowing异常通知方法抛出异常后
@After最终通知无论成功与否都会执行
@Around环绕通知方法前后都能增强,需手动执行目标方法

✳️ 示例:多种通知的写法

package com.qcbyjy.demo3;import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;@Component
@Aspect
public class MyAnnoAspect {@Before("execution(* com.qcbyjy.demo3.OrderServiceImpl.save(..))")public void before() {System.out.println("【前置通知】方法即将执行...");}@AfterReturning("execution(* com.qcbyjy.demo3.OrderServiceImpl.save(..))")public void afterReturning() {System.out.println("【后置通知】方法执行成功!");}@AfterThrowing("execution(* com.qcbyjy.demo3.OrderServiceImpl.save(..))")public void afterThrowing() {System.out.println("【异常通知】方法执行出错!");}@After("execution(* com.qcbyjy.demo3.OrderServiceImpl.save(..))")public void after() {System.out.println("【最终通知】无论如何都会执行!");}@Around("execution(* com.qcbyjy.demo3.OrderServiceImpl.save(..))")public Object around(ProceedingJoinPoint pjp) throws Throwable {System.out.println("【环绕通知-前】准备执行方法...");Object result = pjp.proceed(); // 手动执行目标方法System.out.println("【环绕通知-后】方法执行完毕。");return result;}
}

执行结果:

【环绕通知-前】准备执行方法...
【前置通知】方法即将执行...
业务层:保存订单...
【后置通知】方法执行成功!
【最终通知】无论如何都会执行!
【环绕通知-后】方法执行完毕。

九、纯注解方式(无XML版)

Spring 也支持彻底不用 XML,只写注解。

SpringConfig.java

package com.qcbyjy.demo3;import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.EnableAspectJAutoProxy;@Configuration                 // 声明为配置类(代替xml)
@ComponentScan("com.qcbyjy.demo3")   // 扫描包
@EnableAspectJAutoProxy        // 开启AOP自动代理(代替 <aop:aspectj-autoproxy/>)
public class SpringConfig {
}

测试类修改为:

@ContextConfiguration(classes = SpringConfig.class)

到此为止,我们就实现了一个纯注解的 Spring AOP 项目


🔚 十、总结对比

对比项XML 方式注解方式
配置复杂度需要手动写 <aop:aspect>更简洁,只需加注解
可读性XML 分散、冗长注解集中、直观
推荐使用旧项目/配置多场景✅ 新项目首选

✅ 写在最后

通过注解方式实现 AOP,开发效率更高,代码更清晰。
尤其是结合 Spring Boot 时,几乎只需一个注解 @Aspect 就能搞定切面功能。

http://www.dtcms.com/a/588955.html

相关文章:

  • C++——二叉搜索树
  • 青少年机器人技术等级考试理论综合试卷(一级)2020年9月
  • Redis_9_Set
  • 计算机网络培训课程大庆网站建设优化
  • 网站正在建设中永久wordpress 前台文章
  • Electron 桌面应用开发入门指南:从零开始打造 Hello World
  • 深入解析手机快充技术原理与实现
  • JavaScript 数组方法大全
  • 电子商务网站建设与管理的实验报告个人怎样免费建网站
  • STM32F103学习笔记-16-RCC(第3节)-使用HSE配置系统时钟并使用MCO输出监控系统时钟
  • LeRobot 入门教程(十五)从Hub加载环境
  • HTML DOM 总结
  • 社群经济下开源链动2+1模式AI智能名片S2B2C商城小程序的信任重构机制研究
  • Git 命令大全:从基础到高级操作
  • Git_Rebase
  • 【深度学习|学习笔记】异常检测概论 — 从经典算法到深度学习(含实用 Python 示例)
  • 如何建立一个视频网站html5 手机网站页面实例
  • FlutterPlugin接口实现与插件架构设计
  • 图漾GM461-E1相机专栏
  • Flutter与鸿蒙原生MethodChannel通信机制深度解析
  • Navigation2 行为树架构源码级分析与设计原理
  • 基于时频域霍夫变换的汽车雷达互干扰抑制——论文阅读
  • 贵阳网站建设建站系统怎么找网站是由什么建的
  • 一本通网站1128题:图像模糊处理
  • DrissionPage遇到iframe
  • 基于信号分解的FMCW雷达相互干扰抑制——论文阅读
  • 未来的一些想法和规划
  • 线代强化NO3|线性方程组|特征值和特征向量|矩阵的相似性|实对称矩阵|二次型
  • K8S RD: Docker与Kubernetes运维核心技术整合指南
  • PERL Docker 容器化部署指南