使用自定义注解和Spring AOP实现前后置方法调用

使用自定义注解和Spring AOP实现前后置方法调用

在开发过程中,经常会遇到需要在方法执行前后添加一些逻辑的情况,例如记录日志、性能监控、事务管理等。使用Spring AOP(Aspect-Oriented Programming)和自定义注解,可以方便地实现这些需求。本文将详细介绍如何通过Java和Spring AOP实现一个自定义注解,用于在方法执行前后调用指定的函数。

1. 创建自定义注解

首先,我们创建一个自定义注解 @ExecuteFunctions,并增加一个 beforeParam 参数,用于传递给前置方法。注解的代码如下:

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface ExecuteFunctions {int beforeParam() default 0;
}

这个注解具有一个 beforeParam 参数,默认值为 0,它将用于传递一个整数值给前置方法。

2. 创建服务类

接下来,我们创建一个服务类 FunctionService,其中包含前置和后置方法。前置方法 functionBefore 接收一个整数参数,后置方法 functionAfter 不需要参数。

import org.springframework.stereotype.Service;@Service
public class FunctionService {public void functionBefore(int param) {System.out.println("Function Before Execution with param: " + param);}public void functionAfter() {System.out.println("Function After Execution");}
}
3. 创建切面类

为了在方法执行前后调用指定的函数,我们需要创建一个切面类 FunctionAspect。这个类使用 @Aspect 注解定义一个切面,并使用 @Around 注解定义环绕通知,处理前置和后置函数的执行。

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;import java.lang.reflect.Method;@Aspect
@Component
public class FunctionAspect {@Autowiredprivate FunctionService functionService;@Pointcut("@annotation(executeFunctions)")public void executeFunctionsPointcut(ExecuteFunctions executeFunctions) {}@Around("executeFunctionsPointcut(executeFunctions)")public Object around(ProceedingJoinPoint joinPoint, ExecuteFunctions executeFunctions) throws Throwable {int beforeParam = executeFunctions.beforeParam();// 执行前置函数invokeFunction("functionBefore", beforeParam);Object result = null;try {// 执行目标方法result = joinPoint.proceed();} finally {// 执行后置函数invokeFunction("functionAfter");}return result;}private void invokeFunction(String functionName, int param) throws Exception {Method method = FunctionService.class.getMethod(functionName, int.class);method.invoke(functionService, param);}private void invokeFunction(String functionName) throws Exception {Method method = FunctionService.class.getMethod(functionName);method.invoke(functionService);}
}

FunctionAspect 类中,我们定义了一个 @Around 通知,用于在目标方法执行前后调用前置和后置方法。invokeFunction 方法通过反射调用带有参数或不带参数的方法。

4. 使用自定义注解

在需要执行前置和后置函数的方法上使用 @ExecuteFunctions 注解,并指定 beforeParam 参数。例如,在一个控制器类中使用这个注解:

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
public class DemoController {@Autowiredprivate FunctionService functionService;@ExecuteFunctions(beforeParam = 42)@GetMapping("/test")public String test() {System.out.println("Executing target method");return "Hello, World!";}
}
5. 启动Spring Boot应用

确保你的Spring Boot应用正确配置并启动。访问 /test 路径,应该会看到如下输出:

Function Before Execution with param: 42
Executing target method
Function After Execution
解释
  1. 自定义注解

    • @ExecuteFunctions 注解增加了一个 beforeParam 参数,用于传递一个整数值给 functionBefore 方法。
  2. 服务类

    • FunctionService 定义了带有 int 参数的 functionBefore 方法和无参数的 functionAfter 方法。
  3. 切面类

    • FunctionAspect 类使用 @Aspect 注解定义一个切面,使用 @Around 注解定义了环绕通知,处理前置和后置函数的执行。
    • invokeFunction 方法通过反射调用带有 int 参数的 functionBefore 方法,并在方法参数不为空时传递参数。
  4. 控制器

    • DemoController 类中,使用 @ExecuteFunctions 注解标注需要执行前置和后置函数的方法,并指定 beforeParam 参数。

通过这种方式,我们实现了一个灵活的解决方案,可以在方法执行前后调用指定的函数,并且支持通过注解参数传递值给前置函数。这样的实现不仅提高了代码的可读性和可维护性,还增强了代码的扩展性和复用性。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/38971.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

适用于高海拔地区的工业路由器产品

1、西藏背景 西藏,这个位于中国西南部的神秘之地,以其雄伟壮观、神奇瑰丽的自然风光和深厚的文化底蕴,被无数人视为心中的圣地。这里属于高原性气候,具有气温低、气压低,降水少,生态环境十分恶劣。西藏被誉…

学懂C#编程:常用高级技术——学会C#的高级特性 LINQ

LINQ(Language Integrated Query)是C#中的一项强大特性,它允许开发者以一种统一的方式查询和操作各种数据源,如集合、数据库、XML等。LINQ将查询功能直接集成到C#语言中,使得数据查询和操作变得更加直观和高效。 LINQ…

python 分析nginx的error.log日志 然后写入到 mongodb当中 并且解决mongodb无法根据id删除数据的问题

废话不多说 直接上代码 import re import os import pymongo import uuid import bson def extract_unresolved_info(log_path):unresolved_info []with open(log_path, r) as file:log_text file.read()lines log_text.split("\n")for line in lines:# 这种属于主…

软件测试面试200问【答案+文档】

🍅 视频学习:文末有免费的配套视频可观看 🍅 点击文末小卡片,免费获取软件测试全套资料,资料在手,涨薪更快 1、B/S架构和C/S架构区别 B/S 只需要有操作系统和浏览器就行,可以实现跨平台&#x…

雷池WAF+Modsecurity安装防护及系统加固

君衍. 一、雷池WAF1、什么是雷池2、什么是WAF3、雷池的功能4、WAF部署架构5、整体检测流程 二、雷池WAF环境依赖1、查看本地CPU架构2、Docker安装2.1 卸载旧版本2.2 安装yum-utils工具包2.3 设置镜像仓库2.4 安装docker2.5 启动docker并查看版本 3、Docker Compose安装3.1 卸载…

QueryClientProvider is not defined

QueryClientProvider is not defined 运行一个svelte的项目,报错如上,前后查找解决不了,然后没办法, 本来是用yarn 安装的依赖,改用npm install,再次运行就成功了

制氢厂氢气泄漏安全监测:氢气传感器守护“氢”安全

随着全球能源结构的转型和清洁能源的需求日益增长,氢能作为一种高效、清洁的能源载体,受到了广泛关注。制氢厂作为氢能产业的重要组成部分,其安全问题也日益凸显。在制氢过程中,氢气泄漏是潜在的安全隐患之一,因此&…

centos 安装zabbix 6.4.16 server client

Zabbix Server 采用源码包部署,数据库采用 MySQL8.0 版本,zabbix-web 使用 nginxphp 来实现。具体信息如下: 软件名 版本 安装方式 Zabbix Server 6.4.16 源码安装 Zabbix Agent 6.4.16 源码安装 MySQL 8.0.28 yum安装 Nginx 1.…

【Python】Python检查文件或文件夹路径是否存在

目录 问题背景 功能实现 代码解析 问题背景 在某些场景中,我们需要在使用文件或者文件夹前判断一下其是否存在,以防出现一些意外的报错,为了更好的使用该功能,可以把这个功能封装成为一个函数,具体实现如下: 功能实…

大数据学习之Clickhouse

Clickhouse-23.2.1.2537 学习 一、Clickhouse概述 clickhouse 官网网址:https://clickhouse.com/ ClickHouse是一个用于联机分析(OLAP)的列式数据库管理系统(DBMS)。 OLTP(联机事务处理系统)例如mysql等关系型数据库,在对于存储小数据量的时候&#xff…

基于IDEA调试模式与StopWatch工具类如何优雅实现Java代码执行时间检测统计

目录 1.1、前言1.2、开发环境1.3、传统方式实现1.4、优雅方式实现1.4.1、StopWatch工具简介1.4.2、实现步骤 1.1、前言 作为程序员在我们的日常编码过程中经常需要统计一段代码或者一个方法的执行时间,尤其是当以一个接口的执行响应时间比较长需要优化的时候&#x…

华为OD机考题(HJ41 称砝码)

前言 经过前期的数据结构和算法学习,开始以OD机考题作为练习题,继续加强下熟练程度。有需要的可以同步练习下。 描述 现有n种砝码,重量互不相等,分别为 m1,m2,m3…mn ; 每种砝码对应的数量为 x1,x2,x3...xn 。现在要…

基于PHP技术的校园论坛设计的设计与实现08586

基于PHP技术的校园论坛设计的设计与实现 摘 要 本项目旨在基于PHP技术设计与实现一个校园论坛系统,以提供一个功能丰富、用户友好的交流平台。该论坛系统将包括用户注册与登录、帖子发布与回复、个人信息管理等基本功能,并结合社交化特点,增强…

Vulkan学习——渲染3D模型

摘要:本文简要描述了Vulkan渲染一个3D模型需要做的事情,不会对太细节的内容进行深究。   关键字:Vulkan,Render,3D 源码 1 简介 1.1 Vulkan简介 Vulkan是一个低开销、跨平台的二维、三维图形与计算的应用程序接口(API&#x…

创意无界:探索国产创成式填充的无限潜力

在数字艺术与设计的世界中,创新技术不断涌现,而"创成式填充"无疑是其中的一颗璀璨新星。今天米兔要安利的这款国产ps插件-StartaAI拥有强大的AI功能,其AI扩图和局部重绘更是成为PS创成式填充的国产平替。 什么是创成式填充&#x…

PADS设置板框提示不闭合的解决办法

一般是选中join,提示不闭合,不能转成板框,其实直接点击close就好了,报错提示里就有提示,让用close命令试试

基于SpringBoot扶农助农政策管理系统设计和实现(源码+LW+调试文档+讲解等)

💗博主介绍:✌全网粉丝10W,CSDN作者、博客专家、全栈领域优质创作者,博客之星、平台优质作者、专注于Java、小程序技术领域和毕业项目实战✌💗 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,…

html页面可加密吗?

问:html页面可加密吗? 答:可以。 问:怎样加密? 答:看图:

VSCode无法识别 node、npm

一、前提 电脑新安装了node.js,在cmd查看node和npm版本没有问题,但是在VSCode无法识别 1.cmd查看版本: 2.VSCode报错信息: 无法将“npm”项识别为 cmdlet、函数、脚本文件或可运行程序的名称。请检查名称的拼写,如果…

面经-计算机基础

1.计算机⽹络 1.1 OSI与TCP/IP各层的结构与功能,都有哪些协议? 计算机网络体系结构 应⽤层 应⽤层 (application-layer )的任务是通过应⽤进程间的交互来完成特定⽹络应⽤。 应⽤层协议定 义的是应⽤进程(进程:主机中正在运⾏的程序&…