springboot 抽出多个接口中都有相同的代码的方法

在Spring Boot中,如果发现多个接口中有重复的代码,可以采用以下几种方式来提取和复用这段代码:

1、使用Service层方法

        如果这段代码的逻辑与业务相关,可以将其封装到一个Service层的方法中,然后在Controller中调用这个方法。

   // SysConfigService.java
   public SysConfig findServerUrlConfig() {
       SysConfig sysConfig = this.findSysConfigByConfigKey("server_url");
       if (sysConfig == null) {
           throw new ConfigNotFoundException("服务地址配置信息为空");
       }
       return sysConfig;
   }

   // Controller.java
   @GetMapping("/endpoint")
   public HttpResponseDto getEndpoint() {
       SysConfig sysConfig = sysConfigService.findServerUrlConfig();
       String serverUrl = sysConfig.getConfigValue();
       // 使用serverUrl ...
   }
   

2、使用Controller Advice

        如果这段代码是与Controller相关的,比如预处理请求或后处理响应,可以使用@ControllerAdvice来创建一个全局的拦截器或处理器。

   @ControllerAdvice
   public class GlobalControllerAdvice {

       @ModelAttribute
       public void addServerUrl(Model model) {
           SysConfig sysConfig = sysConfigService.findSysConfigByConfigKey("server_url");
           if (sysConfig == null) {
               throw new ConfigNotFoundException("服务地址配置信息为空");
           }
           model.addAttribute("serverUrl", sysConfig.getConfigValue());
       }
   }
   

然后在Controller中使用@ModelAttribute的值:

   @GetMapping("/endpoint")
   public HttpResponseDto getEndpoint(@ModelAttribute("serverUrl") String serverUrl) {
       // 使用serverUrl...
   }
   

3、使用AspectJ切面

        如果这段代码是横切关注点,可以使用AspectJ切面来封装这段逻辑。

   @Aspect
   @Component
   public class ServerUrlAspect {

       @Before("execution(* com.example.controller.*.*(..))")
       public void before(JoinPoint joinPoint) {
           SysConfig sysConfig = sysConfigService.findSysConfigByConfigKey("server_url");
           if (sysConfig == null) {
               throw new ConfigNotFoundException("服务地址配置信息为空");
           }
           // 可以通过某种方式将sysConfig或其值传递给被切的方法
       }
   }

4、使用自定义注解和处理器

        如果这段代码只适用于特定的场景,可以创建一个自定义注解和对应的处理器来处理这段逻辑。

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

   @LoadServerUrl
   @GetMapping("/endpoint")
   public HttpResponseDto getEndpoint() {
       // 在这里使用serverUrl
   }
   

        处理器:

   @Aspect
   @Component
   public class LoadServerUrlAspect {

       @Around("@annotation(LoadServerUrl)")
       public Object loadServerUrl(ProceedingJoinPoint joinPoint) throws Throwable {
           SysConfig sysConfig = sysConfigService.findSysConfigByConfigKey("server_url");
           if (sysConfig == null) {
               throw new ConfigNotFoundException("服务地址配置信息为空");
           }
           // 可以通过某种方式将sysConfig或其值传递给被切的方法
           return joinPoint.proceed();
       }
   }

如果是纯粹的业务逻辑,推荐使用Service层方法;

如果是与请求处理紧密相关的逻辑,可以考虑使用@ControllerAdvice或自定义注解;

如果是横切关注点,使用AspectJ切面是最佳选择。

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-07-11 15:14:03       67 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-07-11 15:14:03       71 阅读
  3. 在Django里面运行非项目文件

    2024-07-11 15:14:03       58 阅读
  4. Python语言-面向对象

    2024-07-11 15:14:03       69 阅读

热门阅读

  1. OpenJudge | 最高的分数

    2024-07-11 15:14:03       20 阅读
  2. springmvc 如何对接接口

    2024-07-11 15:14:03       22 阅读
  3. VUE2用elementUI实现父组件中校验子组件中的表单

    2024-07-11 15:14:03       22 阅读
  4. 解释一下DecorView和Window之间的交互。

    2024-07-11 15:14:03       24 阅读
  5. 【AI原理解析】-目标检测概述

    2024-07-11 15:14:03       19 阅读
  6. 24/07/10数据结构(4.1209)单链表OJ

    2024-07-11 15:14:03       22 阅读