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

Spring AOP注解案例

Spring AOP注解案例

applicationContext.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:aop="http://www.springframework.org/schema/aop"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/aophttp://www.springframework.org/schema/aop/spring-aop.xsdhttp://www.springframework.org/schema/contexthttp://www.springframework.org/schema/context/spring-context.xsd"><!-- 启用注解扫描 --><context:component-scan base-package="com.hxj"/><!-- 启用AspectJ自动代理 --><aop:aspectj-autoproxy/><!-- 你的业务bean在这里定义 --><!--<bean id="yourService" class="your.package.name.YourServiceImpl"/><bean id="yourAspect" class="your.package.name.YourAspect"/>--></beans>

接口代码

package com.hxj.dao;public interface UserService {public void addUser(String username);public void deleteUser(String username);public String getUser(String username);
}

接口实现类

package com.hxj.dao;import org.springframework.stereotype.Component;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements UserService{@Overridepublic void addUser(String username) {System.out.println("正在添加用户: " + username);// 模拟业务逻辑if (username == null || username.isEmpty()) {throw new IllegalArgumentException("用户名不能为空");}}@Overridepublic void deleteUser(String username) {System.out.println("正在删除用户: " + username);// 模拟业务逻辑if (username == null || username.isEmpty()) {throw new IllegalArgumentException("用户名不能为空");}}@Overridepublic String getUser(String username) {System.out.println("正在查询用户: " + username);// 模拟业务逻辑return "用户信息: " + username;}
}

切面类

package com.hxj.dao;import org.aspectj.lang.JoinPoint;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.*;
import org.springframework.stereotype.Component;import java.util.Arrays;/*** 日志切面类* 演示各种通知类型的使用*/
@Component  // 1. 告诉Spring这是一个需要管理的Bean
@Aspect  // 2. 告诉Spring这是一个切面类,包含AOP逻辑
public class LoggingAspect {/***定义切入点表达式* 匹配com.hxj.dao包下的所有方法*/@Pointcut("execution(* com.hxj.dao.*.*(..))")public void pic(){}/*** 执行顺序* 当多个通知应用于同一个连接点时,执行顺序如下:* 1.@Around(前置部分)* 2.@Before* 3.目标方法执行* 4.@Around(后置部分)* 5.@After* 6.@AfterReturning(如果方法正常返回)* 7.@AfterThrowing(如果方法抛出异常)*//*** 前置通知: 在目标方法执行之前执行* 特点:*      - 不能阻止目标方法的执行*      - 如果这里抛出异常,会阻止目标方法执行*      - 可以访问方法参数,但不能访问返回值* @param joinPoint 连接点信息*/@Before("pic()")public void logBefore(JoinPoint joinPoint) {System.out.println("======= 前置通知 =======");System.out.println("方法签名: " + joinPoint.getSignature().toShortString());System.out.println("方法参数: " + Arrays.toString(joinPoint.getArgs()));System.out.println("目标对象: " + joinPoint.getTarget().getClass().getSimpleName());
//        throw new RuntimeException("这是在前置通知中抛出的异常");}/*** 后置通知:在目标方法执行后执行(无论是否发生异常)* 特点:*       - 类似于finally块,总是会执行*       - 不能访问方法的返回值*       - 通常用于清理资源或记录方法执行完成的日志*       * @param joinPoint 连接点信息*/@After("pic()")public void logAfter(JoinPoint joinPoint) {System.out.println("======= 后置通知 =======");System.out.println("方法 " + joinPoint.getSignature().getName() + " 执行完毕");}/*** 返回通知:在目标方法成功执行后执行* 特点:*      - 只在目标方法正常完成时执行(没有抛出异常)*      - 可以访问方法的返回值*      - 适合用于记录方法执行结果或对返回值进行处理* @param joinPoint 连接点信息* @param result 方法返回值*/@AfterReturning(pointcut = "pic()", returning = "result")public void logAfterReturning(JoinPoint joinPoint, Object result) {System.out.println("======= 返回通知 =======");System.out.println("方法 " + joinPoint.getSignature().getName() + " 执行成功");System.out.println("返回值: " + result);}/*** 异常通知:在目标方法抛出异常后执行* 特点:*      - 只在目标方法抛出异常时执行*      - 可以访问异常对象*      - 适合用于记录异常信息或对异常进行处理* @param joinPoint 连接点信息* @param ex 异常对象*/@AfterThrowing(pointcut = "pic()", throwing = "ex")public void logAfterThrowing(JoinPoint joinPoint, Exception ex) {System.out.println("======= 异常通知 =======");System.out.println("方法 " + joinPoint.getSignature().getName() + " 执行异常");System.out.println("异常信息: " + ex.getMessage());}/*** 环绕通知:环绕目标方法执行* 特点:*      - 最强大的通知类型*      - 可以控制目标方法是否执行*      - 可以访问方法参数和返回值*      - 必须调用 ProceedingJoinPoint.proceed() 来执行目标方法*      - 可以修改方法参数、返回值或捕获异常* @param joinPoint 连接点信息* @return 方法执行结果* @throws Throwable 可能抛出的异常*/@Around("pic()")public Object logAround(ProceedingJoinPoint joinPoint) throws Throwable {System.out.println("======= 环绕通知开始 =======");long startTime = System.currentTimeMillis();try {// 执行目标方法Object result = joinPoint.proceed();long endTime = System.currentTimeMillis();System.out.println("方法执行时间: " + (endTime - startTime) + "ms");return result;} catch (Throwable throwable) {System.out.println("方法执行出现异常: " + throwable.getMessage());throw throwable;} finally {System.out.println("======= 环绕通知结束 =======");}}/*** 基于自定义注解的切入点*/@Pointcut("@annotation(com.hxj.dao.LogExecutionTime)")public void logExecutionTimeAnnotation() {}/*** 记录方法执行时间的环绕通知* @param joinPoint 连接点信息* @return 方法执行结果* @throws Throwable 可能抛出的异常*/@Around("logExecutionTimeAnnotation()")public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {long startTime = System.currentTimeMillis();Object result = joinPoint.proceed();long endTime = System.currentTimeMillis();System.out.println(joinPoint.getSignature() + " 执行时间: " + (endTime - startTime) + "ms");return result;}
}

测试方法

package com.hxj.test;import com.hxj.dao.PerformanceService;
import com.hxj.dao.UserService;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;public class ApplicationTest {public static void main(String[] args) {// 加载Spring配置文件/** 1. ApplicationContext contextApplicationContext 是Spring的一个核心接口是一个通用的应用上下文接口提供了基本的容器功能,如Bean获取、环境信息等2. ClassPathXmlApplicationContext context2ClassPathXmlApplicationContext 是 ApplicationContext 的具体实现类专门用于从类路径加载XML配置文件提供了更多具体实现类特有的方法推荐使用接口类型(第一种方式)* */ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
//        ClassPathXmlApplicationContext context2 = new ClassPathXmlApplicationContext("applicationContext.xml");// 获取UserService beanUserService userService = context.getBean(UserService.class);System.out.println("========== 正常执行测试 ==========");userService.addUser("张三");//        System.out.println("\n========== 异常执行测试 ==========");
//        try {
//            userService.addUser("");
//        } catch (Exception e) {
//            System.out.println("捕获到异常: " + e.getMessage());
//        }
//
//        System.out.println("\n========== 查询测试 ==========");
//        String result = userService.getUser("李四");
//        System.out.println("查询结果: " + result);
//
//        // 测试自定义注解
//        System.out.println("\n========== 自定义注解测试 ==========");
//        PerformanceService performanceService = context.getBean(PerformanceService.class);
//        try {
//            performanceService.performTask();
//            String processedData = performanceService.processData("test data");
//            System.out.println(processedData);
//        } catch (Exception e) {
//            e.printStackTrace();
//        }}
}
http://www.dtcms.com/a/365249.html

相关文章:

  • AI 重塑就业市场:哪些职业会被替代?又有哪些新岗位正在崛起?
  • 基于https+域名的Frp内网穿透教程(Linux+Nginx反向代理)
  • python数据分析 与spark、hive数据分析对比
  • Gemini CLI源码解析:Agent与上下文管理实现细节
  • 2025年COR IOTJ SCI2区,灾后通信无人机基站位置优化和移动充电无人机路径规划,深度解析+性能实测
  • Aerobits-用于 sUAS 和 UTM/U-Space 的微型 ADS-B 技术(收发器/接收器)和无人机跟踪应答器
  • Grok-4 :AI 基准测试霸主,速度与智能并存——但代价几何?
  • 简述 Java 的异常体系结构。Error 和 Exception 有什么区别?
  • 精通人机协同:使用 LangGraph 构建交互式智能体的综合指南
  • 服务器固件全景地图:从BIOS到BMC,升级背后的安全与性能革命
  • [光学原理与应用-376]:ZEMAX - 优化 - 概述
  • 中通笔试ShowMeBug编程题复盘
  • Ansible 核心功能:循环、过滤器、判断与错误处理全解析
  • 《苍穹外卖》开发环境搭建_后端环境搭建【简单易懂注释版】
  • PL-YOLOv8:基于YOLOv8的无人机实时电力线检测与植被风险预警框架,实现精准巡检与预警
  • 【Spring Cloud微服务】11.微服务通信演义:从飞鸽传书到5G全息,一部消息中间件的进化史诗
  • Git 别名:用简短命令大幅提升开发效率
  • 无人机报警器8G信号技术解析
  • leetcode110. 平衡二叉树
  • 深入解析Java Spliterator(Stream延迟、并行计算核心)
  • 哪些AI生成PPT的软件或网站支持多平台使用?都支持哪些平台?
  • AI生成PPT工具排名:2025年高效办公新选择
  • 关于MySQL数据库连接超时问题及解决办法
  • AR智慧运维系统介绍
  • vue项目打包后dist部署到Nginx
  • 性能测试-jmeter9-直连数据库
  • 深度学习篇---模型组成部分
  • 财务文档处理优化:基于本地运行的PDF合并解决方案
  • 【51单片机】【protues仿真】基于51单片机压力测量仪系统
  • wpf触发器