揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效

简介: 揭秘Spring Boot自定义注解的魔法:三个实用场景让你的代码更加优雅高效

在Spring Boot项目中,自定义注解可以大大简化代码并提高可读性和可维护性。本文将通过三个具体场景展示如何优雅地使用自定义注解来解决实际问题。

场景一:统一的日志记录

在实际开发中,我们经常需要在方法执行前后记录日志。通过自定义注解和AOP,可以优雅地实现这一功能。

1. 创建自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface LogExecutionTime {
}

2. 实现AOP切面:

@Aspect
@Component
public class LogAspect {
 
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);
 
    @Around("@annotation(com.example.LogExecutionTime)")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long start = System.currentTimeMillis();
 
        Object proceed = joinPoint.proceed();
 
        long executionTime = System.currentTimeMillis() - start;
 
        logger.info("{} executed in {} ms", joinPoint.getSignature(), executionTime);
 
        return proceed;
    }
}

3. 使用自定义注解:

@RestController
public class UserController {
 
    @LogExecutionTime
    @GetMapping("/users")
    public List<User> getAllUsers() {
        // 获取用户列表的逻辑
        return userService.findAll();
    }
}
场景二:参数校验

在Spring Boot中,可以使用自定义注解来简化参数校验逻辑。

1. 创建自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
@Constraint(validatedBy = PhoneValidator.class)
public @interface ValidPhone {
    String message() default "Invalid phone number";
    Class<?>[] groups() default {};
    Class<? extends Payload>[] payload() default {};
}

2. 实现校验逻辑:

public class PhoneValidator implements ConstraintValidator<ValidPhone, String> {
 
    private static final String PHONE_PATTERN = "^\\+?[0-9. ()-]{7,25}$";
 
    @Override
    public void initialize(ValidPhone constraintAnnotation) {
    }
 
    @Override
    public boolean isValid(String phoneField, ConstraintValidatorContext context) {
        return phoneField != null && phoneField.matches(PHONE_PATTERN);
    }
}

3. 使用自定义注解:

public class UserDTO {
 
    @ValidPhone
    private String phoneNumber;
 
    // 其他字段和getter、setter
}

4. 控制器中使用参数校验:

@RestController
public class UserController {
 
    @PostMapping("/users")
    public ResponseEntity<String> createUser(@Valid @RequestBody UserDTO userDTO, BindingResult result) {
        if (result.hasErrors()) {
            return ResponseEntity.badRequest().body(result.getAllErrors().toString());
        }
        // 创建用户的逻辑
        return ResponseEntity.ok("User created successfully");
    }
}
场景三:权限控制

通过自定义注解,可以简化权限控制的逻辑。

1. 创建自定义注解:

@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
public @interface RequiresPermission {
    String value();
}

2. 实现AOP切面:

@Aspect
@Component
public class PermissionAspect {
 
    @Autowired
    private PermissionService permissionService;
 
    @Around("@annotation(requiresPermission)")
    public Object checkPermission(ProceedingJoinPoint joinPoint, RequiresPermission requiresPermission) throws Throwable {
        String permission = requiresPermission.value();
        if (!permissionService.hasPermission(permission)) {
            throw new AccessDeniedException("Access denied");
        }
        return joinPoint.proceed();
    }
}

3. 使用自定义注解:

@RestController
public class UserController {
 
    @RequiresPermission("admin")
    @GetMapping("/admin")
    public ResponseEntity<String> getAdminPage() {
        return ResponseEntity.ok("Welcome to admin page");
    }
}

总结

通过自定义注解,结合Spring AOP和Validator,我们可以在Spring Boot项目中优雅地解决各种实际问题。这种方式不仅使代码更加简洁和可维护,还提高了开发效率和代码质量。希望以上的三个实例能够帮助你更好地理解和应用自定义注解。

相关文章
|
13天前
|
Java Spring
在使用Spring的`@Value`注解注入属性值时,有一些特殊字符需要注意
【10月更文挑战第9天】在使用Spring的`@Value`注解注入属性值时,需注意一些特殊字符的正确处理方法,包括空格、引号、反斜杠、新行、制表符、逗号、大括号、$、百分号及其他特殊字符。通过适当包裹或转义,确保这些字符能被正确解析和注入。
|
2天前
|
XML JSON Java
SpringBoot必须掌握的常用注解!
SpringBoot必须掌握的常用注解!
14 4
SpringBoot必须掌握的常用注解!
|
4天前
|
存储 缓存 Java
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
Spring缓存注解【@Cacheable、@CachePut、@CacheEvict、@Caching、@CacheConfig】使用及注意事项
27 2
|
4天前
|
JSON Java 数据库
SpringBoot项目使用AOP及自定义注解保存操作日志
SpringBoot项目使用AOP及自定义注解保存操作日志
18 1
|
11天前
|
存储 Java 数据管理
强大!用 @Audited 注解增强 Spring Boot 应用,打造健壮的数据审计功能
本文深入介绍了如何在Spring Boot应用中使用`@Audited`注解和`spring-data-envers`实现数据审计功能,涵盖从添加依赖、配置实体类到查询审计数据的具体步骤,助力开发人员构建更加透明、合规的应用系统。
|
2月前
|
SQL 监控 druid
springboot-druid数据源的配置方式及配置后台监控-自定义和导入stater(推荐-简单方便使用)两种方式配置druid数据源
这篇文章介绍了如何在Spring Boot项目中配置和监控Druid数据源,包括自定义配置和使用Spring Boot Starter两种方法。
|
23天前
|
人工智能 自然语言处理 前端开发
SpringBoot + 通义千问 + 自定义React组件:支持EventStream数据解析的技术实践
【10月更文挑战第7天】在现代Web开发中,集成多种技术栈以实现复杂的功能需求已成为常态。本文将详细介绍如何使用SpringBoot作为后端框架,结合阿里巴巴的通义千问(一个强大的自然语言处理服务),并通过自定义React组件来支持服务器发送事件(SSE, Server-Sent Events)的EventStream数据解析。这一组合不仅能够实现高效的实时通信,还能利用AI技术提升用户体验。
125 2
|
3月前
|
缓存 Java Maven
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
Java本地高性能缓存实践问题之SpringBoot中引入Caffeine作为缓存库的问题如何解决
|
23天前
|
SQL JSON Java
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
这篇文章介绍了如何在Spring Boot项目中整合MyBatis和PageHelper进行分页操作,并且集成Swagger2来生成API文档,同时定义了统一的数据返回格式和请求模块。
39 1
mybatis使用三:springboot整合mybatis,使用PageHelper 进行分页操作,并整合swagger2。使用正规的开发模式:定义统一的数据返回格式和请求模块
|
4月前
|
Java 测试技术 数据库
Spring Boot中的项目属性配置
本节课主要讲解了 Spring Boot 中如何在业务代码中读取相关配置,包括单一配置和多个配置项,在微服务中,这种情况非常常见,往往会有很多其他微服务需要调用,所以封装一个配置类来接收这些配置是个很好的处理方式。除此之外,例如数据库相关的连接参数等等,也可以放到一个配置类中,其他遇到类似的场景,都可以这么处理。最后介绍了开发环境和生产环境配置的快速切换方式,省去了项目部署时,诸多配置信息的修改。