最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Spring Boot自定义注解:实战案例解析指南
时间:2026-05-25 14:00:01 编辑:袖梨 来源:一聚教程网
自定义注解是Java开发中提升代码效率的利器,通过AOP技术实现功能扩展,让业务逻辑更加清晰。本文将通过5个实战案例详细解析其实现方法。

自定义注解作为元编程的重要工具,能够在保持原有代码结构的前提下,为程序添加额外功能。结合AOP技术使用,可以显著提升代码的可读性和可维护性。
自定义注解有哪些优势?
代码复用
:将通用功能封装到注解中业务解耦
:分离核心业务与辅助功能声明式编程
:通过注解配置行为更直观维护便捷
:统一管理通用逻辑
自定义注解的原理
在Spring Boot框架中,自定义注解的实现基于以下核心机制:
Java注解机制
(通过@interface定义)- AOP技术或拦截器配合反射解析
Spring容器
的运行时自动处理
自定义注解的实现步骤
引入依赖
项目配置文件中需要添加必要的依赖项:
org.springframework.boot spring-boot-starter-aop org.springframework.boot spring-boot-starter-web
定义自定义注解
基础注解定义示例:
import java.lang.annotation.*;
@Target(ElementType.METHOD) // 注解作用目标:方法
@Retention(RetentionPolicy.RUNTIME) // 运行时生效
@Documented
public @interface MyAnnotation {
String value() default "default";
}
核心元注解说明:
@Target:指定作用范围
@Retention:确定生命周期
@Documented:包含在文档中
常见的自定义注解案例
❶ 自定义日志注解
定义注解
实现自动记录方法调用信息的功能
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface MethodLog {
String value() default "";
boolean printArgs() default true;
boolean printResult() default true;
boolean timing() default true;
}
切面实现
日志记录的核心处理逻辑
@Aspect
@Component
@Slf4j
public class MethodLogAspect {
@Around("@annotation(methodLog)")
public Object around(ProceedingJoinPoint joinPoint, MethodLog methodLog) throws Throwable {
String methodName = getMethodName(joinPoint);
String className = joinPoint.getTarget().getClass().getSimpleName();
long startTime = System.currentTimeMillis();
if (methodLog.printArgs()) {
Object[] args = joinPoint.getArgs();
log.info("[{}#{}] 方法调用, 参数: {}", className, methodName, Arrays.toString(args));
}
try {
Object result = joinPoint.proceed();
if (methodLog.printResult()) {
log.info("[{}#{}] 方法返回: {}", className, methodName, result);
}
if (methodLog.timing()) {
long cost = System.currentTimeMillis() - startTime;
log.info("[{}#{}] 方法执行耗时: {}ms", className, methodName, cost);
}
return result;
} catch (Exception e) {
log.error("[{}#{}] 方法执行异常: {}", className, methodName, e.getMessage());
throw e;
}
}
private String getMethodName(ProceedingJoinPoint joinPoint) {
return joinPoint.getSignature().getName();
}
}
使用示例
在控制器方法上应用日志注解
@RestController
@RequestMapping("/api/user")
public class UserController {
@PostMapping
@MethodLog(value = "创建用户", printArgs = true, printResult = true, timing = true)
public User createUser(@RequestBody User user) {
return userService.save(user);
}
}
❷ 自定义参数校验注解
扩展标准校验功能,实现特定业务规则的验证
定义注解
手机号格式校验注解
@Target({ElementType.FIELD, ElementType.PARAMETER})
@Retention(RetentionPolicy.RUNTIME)
@Constraint(validatedBy = PhoneValidator.class)
public @interface Phone {
String message() default "手机号格式错误";
Class>[] groups() default {};
Class extends Payload>[] payload() default {};
}
实现校验器
校验逻辑的具体实现
public class PhoneValidator implements ConstraintValidator{ @Override public boolean isValid(String value, ConstraintValidatorContext context) { return value != null && value.matches("^1[3-9]d{9}$"); } }
使用示例
在DTO字段上应用校验
@RestController
public class RegisterController {
@PostMapping("/register")
public String register(@Valid @RequestBody UserDTO userDTO) {
return "注册成功";
}
public static class UserDTO {
@Phone
private String phone;
}
}
❸ 自定义权限校验注解
实现方法级别的权限控制
定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface CheckPermission {
String value();
}
实现 AOP 权限校验
@Aspect
@Component
public class PermissionAspect {
@Before("@annotation(checkPermission)")
public void check(JoinPoint joinPoint, CheckPermission checkPermission) {
String requiredPermission = checkPermission.value();
String userPermission = "USER";
if (!userPermission.equals(requiredPermission)) {
throw new RuntimeException("权限不足,缺少:" + requiredPermission);
}
}
}
使用示例
@RestController
public class AdminController {
@CheckPermission("ADMIN")
@GetMapping("/admin")
public String adminPage() {
return "管理员页面";
}
}
❹ 自定义分布式限流注解
定义注解
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface RateLimit {
String key() default "";
int limit() default 100;
int timeWindow() default 60;
String message() default "访问过于频繁,请稍后再试";
}
切面实现
@Aspect
@Component
@Slf4j
public class RateLimitAspect {
private final Map limiterMap = new ConcurrentHashMap<>();
@Before("@annotation(rateLimit)")
public void rateLimitCheck(RateLimit rateLimit) {
String key = generateKey(rateLimit);
RateLimiter limiter = limiterMap.computeIfAbsent(key,
k -> RateLimiter.create(rateLimit.limit() / (double) rateLimit.timeWindow()));
if (!limiter.tryAcquire()) {
throw new RuntimeException(rateLimit.message());
}
}
private String generateKey(RateLimit rateLimit) {
String key = rateLimit.key();
if (StringUtils.isEmpty(key
相关文章
-
Twitter网页版快速登录-twitter官网网页版
05-25
-
yandex免登录直达中文版-yandex俄罗斯搜索入口
05-25
-
夸克网盘网页版直达-夸克浏览器云存储一键登录
05-25
-
Mail.ru官网如何快速登录-Mail.ru官网登录入口在哪
05-25
-
樱花动漫最新版本免费下载入口-樱花动漫官方APP正版安装包安卓版
05-25
-
高清电影下载软件推荐-好用的电影下载工具分享
05-25