揭秘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项目中优雅地解决各种实际问题。这种方式不仅使代码更加简洁和可维护,还提高了开发效率和代码质量。希望以上的三个实例能够帮助你更好地理解和应用自定义注解。

相关文章
|
16天前
|
Java Spring
【Spring】方法注解@Bean,配置类扫描路径
@Bean方法注解,如何在同一个类下面定义多个Bean对象,配置扫描路径
148 73
|
11天前
|
Java Spring 容器
【SpringFramework】Spring IoC-基于注解的实现
本文主要记录基于Spring注解实现IoC容器和DI相关知识。
45 21
|
16天前
|
存储 Java Spring
【Spring】获取Bean对象需要哪些注解
@Conntroller,@Service,@Repository,@Component,@Configuration,关于Bean对象的五个常用注解
|
16天前
|
Java Spring
【Spring配置】idea编码格式导致注解汉字无法保存
问题一:对于同一个项目,我们在使用idea的过程中,使用汉字注解完后,再打开该项目,汉字变成乱码问题二:本来a项目中,汉字注解调试好了,没有乱码了,但是创建出来的新的项目,写的注解又成乱码了。
|
24天前
|
NoSQL Java Redis
Spring Boot 自动配置机制:从原理到自定义
Spring Boot 的自动配置机制通过 `spring.factories` 文件和 `@EnableAutoConfiguration` 注解,根据类路径中的依赖和条件注解自动配置所需的 Bean,大大简化了开发过程。本文深入探讨了自动配置的原理、条件化配置、自定义自动配置以及实际应用案例,帮助开发者更好地理解和利用这一强大特性。
83 14
|
1月前
|
Java 关系型数据库 数据库
京东面试:聊聊Spring事务?Spring事务的10种失效场景?加入型传播和嵌套型传播有什么区别?
45岁老架构师尼恩分享了Spring事务的核心知识点,包括事务的两种管理方式(编程式和声明式)、@Transactional注解的五大属性(transactionManager、propagation、isolation、timeout、readOnly、rollbackFor)、事务的七种传播行为、事务隔离级别及其与数据库隔离级别的关系,以及Spring事务的10种失效场景。尼恩还强调了面试中如何给出高质量答案,推荐阅读《尼恩Java面试宝典PDF》以提升面试表现。更多技术资料可在公众号【技术自由圈】获取。
|
2月前
|
前端开发 Java 开发者
Spring MVC中的请求映射:@RequestMapping注解深度解析
在Spring MVC框架中,`@RequestMapping`注解是实现请求映射的关键,它将HTTP请求映射到相应的处理器方法上。本文将深入探讨`@RequestMapping`注解的工作原理、使用方法以及最佳实践,为开发者提供一份详尽的技术干货。
159 2
|
安全 Java Android开发
SpringBoot 代码混淆方案 ProGuard
在软件开发中,代码混淆是故意创建人类难以理解的源代码或机器代码的行为。代码混淆处理修改了可部署的文件,因此黑客很难从中读取信息,但仍然保持完整的功能。这最初是为 android 平台引入的。它现在能够支持 SpringBoot 2。
|
3月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 实现动态路由和菜单功能,快速搭建前后端分离的应用框架。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,包括版本兼容性、安全性、性能调优等方面。
210 1
|
2月前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
141 62