2025-03-26
编程
00
请注意,本文编写于 32 天前,最后修改于 32 天前,其中某些信息可能已经过时。

目录

1. 定义自定义注解
2. 实现注解的功能
示例:记录方法执行时间
3. 使用自定义注解
4. 扩展:自定义注解的应用场景
(1) 权限校验
(2) 日志记录
(3) 缓存管理
5. 总结

在 Spring Boot 中,除了使用框架提供的注解外,我们还可以根据业务需求自定义注解。自定义注解可以用于简化代码逻辑、增强代码可读性、实现特定功能(如权限校验、日志记录等)。以下是创建和使用自定义注解的步骤及相关示例。

1. 定义自定义注解

自定义注解通过 @interface 关键字来定义。注解中可以包含属性,这些属性类似于方法的声明。

java
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 "执行时间"; // 可选属性,默认值为"执行时间" }
  • @Target:指定注解的作用目标,例如类、方法、字段等。
  • @Retention:指定注解的生命周期,常见值有:
    • RetentionPolicy.SOURCE:仅在源码中保留。
    • RetentionPolicy.CLASS:编译后保留在字节码文件中,但运行时不可用。
    • RetentionPolicy.RUNTIME:编译后保留在字节码文件中,并在运行时可用。
  • value():注解的默认属性,可以通过 @LogExecutionTime("自定义描述") 的方式传入值。

2. 实现注解的功能

要让注解生效,通常需要结合 AOP(面向切面编程) 来实现。以下是一个简单的例子,展示如何使用 AOP 实现注解的功能。

示例:记录方法执行时间

java
import org.aspectj.lang.ProceedingJoinPoint; import org.aspectj.lang.annotation.Around; import org.aspectj.lang.annotation.Aspect; import org.springframework.stereotype.Component; @Aspect @Component public class LogExecutionTimeAspect { @Around("@annotation(logExecutionTime)") // 拦截带有 @LogExecutionTime 注解的方法 public Object logExecutionTime(ProceedingJoinPoint joinPoint, LogExecutionTime logExecutionTime) throws Throwable { long startTime = System.currentTimeMillis(); // 执行被拦截的方法 Object result = joinPoint.proceed(); long executionTime = System.currentTimeMillis() - startTime; // 输出日志信息 System.out.println(logExecutionTime.value() + ": " + executionTime + " ms"); return result; } }
  • @Around:拦截带有 @LogExecutionTime 注解的方法,执行前后进行处理。
  • ProceedingJoinPoint:表示被拦截的方法,调用 proceed() 方法执行原方法逻辑。
  • logExecutionTime.value():获取注解中定义的属性值。

3. 使用自定义注解

在需要统计执行时间的方法上添加 @LogExecutionTime 注解:

java
import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class DemoController { @GetMapping("/test") @LogExecutionTime("测试接口") // 使用自定义注解 public String test() throws InterruptedException { Thread.sleep(1000); // 模拟耗时操作 return "Hello, World!"; } }

当访问 /test 接口时,控制台会输出类似以下内容:

测试接口: 1001 ms

4. 扩展:自定义注解的应用场景

(1) 权限校验

通过自定义注解实现接口级别的权限控制。例如:

java
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface RequiresPermission { String[] value(); // 需要的权限列表 }

然后在 AOP 中实现权限校验逻辑。

(2) 日志记录

通过自定义注解记录用户操作日志。例如:

java
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogOperation { String value() default ""; // 操作描述 }

在 AOP 中捕获方法参数并记录到日志系统。

(3) 缓存管理

通过自定义注解实现方法级别的缓存功能。例如:

java
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface CacheResult { String key(); // 缓存的键 int expire() default 60; // 缓存过期时间(秒) }

在 AOP 中实现缓存逻辑。


5. 总结

自定义注解的核心是通过注解元信息(如属性、目标类型等)配合 AOP 或其他机制(如反射)来实现特定功能。它可以帮助开发者将通用逻辑从具体业务代码中抽离出来,从而提高代码的复用性和可维护性。