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

详细介绍一下springboot自定义注解的使用方法

在Spring Boot中,自定义注解通常结合AOP(面向切面编程)实现特定功能,如日志记录、权限校验等。以下是详细的使用步骤和示例:


1. 添加依赖

确保项目中包含Spring AOP依赖(Spring Boot Starter AOP):

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-aop</artifactId>
</dependency>

2. 定义自定义注解

使用Java元注解(如@Target, @Retention)创建自定义注解。

示例:记录方法执行时间的注解

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

@Target(ElementType.METHOD) // 注解作用在方法上
@Retention(RetentionPolicy.RUNTIME) // 运行时保留
public @interface LogExecutionTime {
    String value() default ""; // 可选参数
}

3. 创建切面类处理注解

通过AOP切面拦截带有自定义注解的方法,实现具体逻辑。

示例:记录方法执行时间的切面

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.springframework.stereotype.Component;

@Aspect // 声明为切面类
@Component // 注册为Spring Bean
public class LogExecutionTimeAspect {

    // 定义切入点:所有被@LogExecutionTime注解的方法
    @Around("@annotation(LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();
        
        // 执行目标方法
        Object result = joinPoint.proceed();
        
        long endTime = System.currentTimeMillis();
        long duration = endTime - startTime;
        
        // 获取方法名和注解参数
        String methodName = joinPoint.getSignature().getName();
        LogExecutionTime annotation = joinPoint.getTarget().getClass()
                .getMethod(methodName, joinPoint.getMethod().getParameterTypes())
                .getAnnotation(LogExecutionTime.class);
        String tag = annotation.value();
        
        System.out.println("方法 " + methodName + " 执行耗时: " + duration + "ms" + 
                           (!tag.isEmpty() ? " [标签: " + tag + "]" : ""));
        return result;
    }
}

4. 在业务代码中使用注解

在需要增强的方法上添加自定义注解。

示例:在Service中使用

@Service
public class SampleService {

    @LogExecutionTime("示例服务") // 使用自定义注解
    public void performTask() {
        // 模拟耗时操作
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
    }
}

5. 测试注解效果

调用带有注解的方法,查看控制台输出。

示例:测试类

@SpringBootTest
public class SampleServiceTest {

    @Autowired
    private SampleService sampleService;

    @Test
    public void testLogExecutionTime() {
        sampleService.performTask();
        // 控制台输出:方法 performTask 执行耗时: 1000ms [标签: 示例服务]
    }
}

常见应用场景

  1. 日志记录:自动记录方法入参、返回值、异常信息。
  2. 权限校验:通过注解拦截请求,检查用户权限。
  3. 缓存控制:根据注解配置自动缓存方法结果。
  4. 事务管理:自定义事务控制策略。
  5. 限流/熔断:实现接口访问频率限制。

注意事项

  1. 确保切面生效:切面类需被Spring管理(使用@Component)。
  2. 正确设置注解生命周期@Retention(RetentionPolicy.RUNTIME)
  3. 切入点表达式:检查@Around中的表达式是否正确匹配注解。
  4. 代理模式:Spring AOP默认使用JDK动态代理,对接口有效;若需代理类,可切换为CGLIB(在Spring Boot中通过spring.aop.proxy-target-class=true配置)。

高级用法

  • 组合注解:将自定义注解与Spring注解结合,简化配置。
    @Target(ElementType.METHOD)
    @Retention(RetentionPolicy.RUNTIME)
    @RequestMapping(method = RequestMethod.GET, path = "/info")
    public @interface GetInfo {}
    
  • 注解继承:通过@Inherited让子类继承父类的注解。

通过以上步骤,你可以灵活创建并应用自定义注解,增强代码的可读性和复用性。

相关文章:

  • 【强化学习】Isaac sim 4.5 UI简介
  • [KEIL]单片机技巧 01
  • C#知识|泛型Generic概念与方法
  • 存贮论模型案例与Matlab实现
  • Ubuntu显卡服务器黑屏无响应的维护日志
  • 【Vue3】实现一个高可用的 markdown 显示组件
  • 【C++/数据结构】栈
  • LeetCode 718 - 最长重复子数组
  • VADv2: 基于矢量表征和概率规划的E2E架构
  • 《英雄无敌3:死亡阴影》游戏秘籍
  • 使用sam-vit-base 模型在caltech256 数据集上实现图片召回
  • 算法题笔记(自用)——Python
  • PHP实现国密SM4算法,银行系统加密算法,JAVA和PHP可相互转换(附完整源码)
  • 矩阵基本概念
  • Spring Boot 自定义 Starter 完整实战手册
  • QT:Graphics View的坐标系介绍
  • 消息中间件应用的常见问题与方案?
  • JS :移除数组中的指定数据
  • LeetCode 热题 100 53. 最大子数组和
  • 老牌工具,16年依然抗打!
  • 泽连斯基:正在等待俄方确认参加会谈的代表团组成
  • “中国神湖”加快放大资源规模!3亿美元换海外年产380万吨钾盐项目
  • 北京13日冰雹过后,已受理各险种报案近3万件
  • 中国至越南河内国际道路运输线路正式开通
  • Manus向全球用户开放注册
  • 高波︱忆陈昊:在中年之前离去