在 Spring Boot 中,除了使用框架提供的注解外,我们还可以根据业务需求自定义注解。自定义注解可以用于简化代码逻辑、增强代码可读性、实现特定功能(如权限校验、日志记录等)。以下是创建和使用自定义注解的步骤及相关示例。
自定义注解通过 @interface
关键字来定义。注解中可以包含属性,这些属性类似于方法的声明。
javaimport 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("自定义描述")
的方式传入值。要让注解生效,通常需要结合 AOP(面向切面编程) 来实现。以下是一个简单的例子,展示如何使用 AOP 实现注解的功能。
javaimport 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()
:获取注解中定义的属性值。在需要统计执行时间的方法上添加 @LogExecutionTime
注解:
javaimport 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
通过自定义注解实现接口级别的权限控制。例如:
java@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RequiresPermission {
String[] value(); // 需要的权限列表
}
然后在 AOP 中实现权限校验逻辑。
通过自定义注解记录用户操作日志。例如:
java@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogOperation {
String value() default ""; // 操作描述
}
在 AOP 中捕获方法参数并记录到日志系统。
通过自定义注解实现方法级别的缓存功能。例如:
java@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheResult {
String key(); // 缓存的键
int expire() default 60; // 缓存过期时间(秒)
}
在 AOP 中实现缓存逻辑。
自定义注解的核心是通过注解元信息(如属性、目标类型等)配合 AOP 或其他机制(如反射)来实现特定功能。它可以帮助开发者将通用逻辑从具体业务代码中抽离出来,从而提高代码的复用性和可维护性。