最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

一文詳解SpringBoot中控制器的動態(tài)注冊與卸載

 更新時間:2025年07月06日 10:59:52   作者:風象南  
在項目開發(fā)中,通過動態(tài)注冊和卸載控制器功能,可以根據(jù)業(yè)務場景和項目需要實現(xiàn)功能的動態(tài)增加、刪除,提高系統(tǒng)的靈活性和可擴展性,下面我們就來看看SpringBoot中控制器動態(tài)注冊和卸載的詳細教程

在項目開發(fā)中,通過動態(tài)注冊和卸載控制器功能,可以根據(jù)業(yè)務場景和項目需要實現(xiàn)功能的動態(tài)增加、刪除,提高系統(tǒng)的靈活性和可擴展性。

本文將介紹如何在 SpringBoot 中實現(xiàn)控制器的動態(tài)注冊和卸載。

項目結構

src
└── main
    ├── java
    │   └── com
    │       └── example
    │           ├── DynamicControllerApplication.java
    │           ├── controller
    │           │   ├── DemoController.java
    │           │   └── DynamicControllerRegistry.java
    │           │   └── DynamicController.java
    │           │   └── ControllerManagement.java
    │           └── config
    │               └── WebConfig.java
    └── resources
        └── application.properties

1. 創(chuàng)建 Spring Boot 啟動類

首先,創(chuàng)建一個啟動類 DynamicControllerApplication.java。

package com.example;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DynamicControllerApplication {
    public static void main(String[] args) {
        SpringApplication.run(DynamicControllerApplication.class, args);
    }
}

2. 創(chuàng)建一個測試控制器

接下來,我們創(chuàng)建一個控制器 DemoController.java,該控制器將返回簡單的字符串響應。

// 動態(tài)控制器注解
@Target({ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface DynamicController {

    // 啟動時注冊
    boolean startupRegister() default true;

}

// 測試控制器
package com.example.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@RequestMapping("/demo")
@DynamicController(startupRegister = false)
public class DemoController {

    @GetMapping("/hello")
    public String hello() {
        return "Hello from Dynamic Controller!";
    }

}

3. 創(chuàng)建動態(tài)控制器注冊類

然后,我們創(chuàng)建一個 DynamicControllerRegistry.java 類,用于動態(tài)注冊和卸載控制器。

package com.example.controller;

import cn.hutool.core.util.ReflectUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class DynamicControllerRegistry {

    @Autowired
    private ApplicationContext applicationContext;

    @Autowired
    private RequestMappingHandlerMapping requestMappingHandlerMapping;

    private final Map<String, String> registeredControllers = new HashMap<>();

    public String registerController(Object controller,String methodName) {
        Class<?> controllerClass = controller.getClass();
        String key = key(controllerClass,methodName);
        String url = "";
        if (!registeredControllers.containsKey(key)) {
            Method method = ReflectUtil.getMethod(controllerClass,methodName);
            RequestMapping methodMapping = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
            RequestMapping requestMapping = controllerClass.getAnnotation(RequestMapping.class);

            url = getMethodUrl(requestMapping,methodMapping);
            // 注冊控制器
            requestMappingHandlerMapping.registerMapping(
                    RequestMappingInfo.paths(url).methods(methodMapping.method()).build(),
                    controller,method
            );
            registeredControllers.put(key,url);
        }else{
            url = registeredControllers.get(key);
            log.warn("controller already registered:{}",url);
        }
        return url;
    }

    public String unregisterController(Class<?> controllerClass,Method method) {
        RequestMapping methodMapping = AnnotatedElementUtils.findMergedAnnotation(method, RequestMapping.class);
        RequestMapping requestMapping = controllerClass.getAnnotation(RequestMapping.class);
        String url = getMethodUrl(requestMapping,methodMapping);
        RequestMappingInfo mappingInfo = RequestMappingInfo.paths(url).methods(methodMapping.method()).build();
        requestMappingHandlerMapping.unregisterMapping(mappingInfo);
        registeredControllers.remove(key(controllerClass,method.getName()));
        log.info("unregister controller:{}", url);
        return url;
    }

    public String unregisterController(Class<?> controllerClass,String methodName) {
        Method method = ReflectUtil.getMethod(controllerClass,methodName);
        return unregisterController(controllerClass,method);
    }

    private String key(Class<?> controllerClass, String method){
        return controllerClass.getName() + "." + method;
    }

    private String getMethodUrl(RequestMapping requestMapping,RequestMapping methodMapping){
        String baseUrl = "";
        String url = "";
        if(requestMapping != null){
            baseUrl = requestMapping.value()[0];
        }
        if(methodMapping != null) {
            String[] values = methodMapping.value();
            if (values.length > 0) {
                url = baseUrl + values[0];
            }
        }
        return url;
    }

}

4. 創(chuàng)建 Web 配置類

創(chuàng)建配置類 WebConfig.java ,實現(xiàn)項目啟動時將不需要注冊的控制器進行卸載。

package com.example.config;

import cn.hutool.core.util.ClassUtil;
import com.example.controller.DynamicController;
import com.example.controller.DynamicControllerRegistry;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.AnnotatedElementUtils;
import org.springframework.core.annotation.AnnotationUtils;
import org.springframework.web.bind.annotation.RequestMapping;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.Set;

@Configuration
@Slf4j
public class WebConfig {

    @Autowired
    private DynamicControllerRegistry dynamicControllerRegistry;

    @Bean
    public Void unregisterDynamicController() {
        Set<Class<?>> classes = ClassUtil.scanPackageByAnnotation("com.example", DynamicController.class);
        for(Class<?> clazz : classes) {
            DynamicController dynamicController = clazz.getAnnotation(DynamicController.class);
            boolean needRegister = dynamicController.startupRegister();
            if(needRegister) {
                continue;
            }

            // 默認不需要注冊的controller,需要在啟動時注銷掉
            RequestMapping requestMapping = clazz.getAnnotation(RequestMapping.class);
            Method[] methods = clazz.getDeclaredMethods();
            for(Method method : methods) {
                dynamicControllerRegistry.unregisterController(clazz,method);
            }
        }

        return null;
    }
}

5. 創(chuàng)建動態(tài)控制器注冊和卸載控制器

創(chuàng)建一個新的控制器 ControllerManagement.java,用于處理控制器的注冊和卸載請求。

package com.example.controller;

import cn.hutool.extra.spring.SpringUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/controller")
public class ControllerManagement {

    @Autowired
    private DynamicControllerRegistry dynamicControllerRegistry;

    @PostMapping("/register")
    public String registerController(@RequestParam String controllerBeanName, @RequestParam String methodName) {
        Object controller = SpringUtil.getBean(controllerBeanName);
        String url = dynamicControllerRegistry.registerController(controller, methodName);
        return "Controller registered at: " + url;
    }

    @DeleteMapping("/unregister")
    public String unregisterController(@RequestParam String controllerBeanName, @RequestParam String methodName) {
        Object controller = SpringUtil.getBean(controllerBeanName);
        String url = dynamicControllerRegistry.unregisterController(controller.getClass(),methodName);
        return "Controller unregistered from: " + url;
    }
}

6. 測試注冊控制器

1. 啟動服務

2. 訪問 http://localhost:8080/demo/hello ,此時應該是404,因為沒有注冊控制器

3. POST http://localhost:8080/controller/register?methodName=hello&controllerBeanName=demoController 注冊控制器

4. 再次訪問 http://localhost:8080/demo/hello

7. 卸載控制器

1. POST http://localhost:8080/controller/unregister?methodName=hello&controllerBeanName=demoController 卸載控制器

2. 再次訪問 <http://localhost:8080/demo/hello>,此時應該是404,因為控制器已被卸載

結論

通過以上步驟,我們實現(xiàn)了在 Spring Boot 中動態(tài)注冊和卸載控制器的功能。

這樣的實現(xiàn)能夠根據(jù)實際需求動態(tài)增減功能。

到此這篇關于一文詳解SpringBoot中控制器的動態(tài)注冊與卸載的文章就介紹到這了,更多相關SpringBoot控制器注冊與卸載內容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關文章希望大家以后多多支持腳本之家!

相關文章

  • Java實現(xiàn)屏幕截圖及剪裁

    Java實現(xiàn)屏幕截圖及剪裁

    這是一篇入門級文章,高手請略過。在這篇文章中我們將學習如何用 Java 對圖像進行剪裁并將剪裁出來的部分單獨保存到文件中。
    2014-09-09
  • Java Swing組件下拉菜單控件JComboBox用法示例

    Java Swing組件下拉菜單控件JComboBox用法示例

    這篇文章主要介紹了Java Swing組件下拉菜單控件JComboBox用法,結合具體實例形式分析了Swing組件下拉菜單控件JComboBox的具體定義、使用方法及相關使用注意事項,需要的朋友可以參考下
    2017-11-11
  • SpringBoot+EasyExcel實現(xiàn)自定義復雜樣式導入導出

    SpringBoot+EasyExcel實現(xiàn)自定義復雜樣式導入導出

    這篇文章主要為大家詳細介紹了SpringBoot如何結果EasyExcel實現(xiàn)自定義復雜樣式導入導出功能,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下
    2025-07-07
  • 業(yè)務系統(tǒng)的Prometheus實踐示例詳解

    業(yè)務系統(tǒng)的Prometheus實踐示例詳解

    這篇文章主要為大家介紹了業(yè)務系統(tǒng)的Prometheus實踐示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2023-04-04
  • java screen的配置詳解及注意事項

    java screen的配置詳解及注意事項

    這篇文章主要介紹了java screen的配置詳解及注意事項的相關資料,需要的朋友可以參考下
    2017-07-07
  • Spring實現(xiàn)類私有方法的幾個問題(親測通用解決方案)

    Spring實現(xiàn)類私有方法的幾個問題(親測通用解決方案)

    現(xiàn)實的業(yè)務場景中,可能需要對Spring的實現(xiàn)類的私有方法進行測試。本文給大家分享Spring實現(xiàn)類私有方法面臨的幾個問題及解決方案,感興趣的朋友跟隨小編一起看看吧
    2021-06-06
  • Java 方法遞歸的思路詳解

    Java 方法遞歸的思路詳解

    程序調用自身的編程技巧稱為遞歸( recursion)。遞歸做為一種算法在程序設計語言中廣泛應用。但是如果沒終止條件會造成死循環(huán),所以遞歸代碼里要有結束自調自的條件,接下來講解一下學習遞歸的思路
    2022-04-04
  • 32位和64位皆適用的MyEclipse安裝教程

    32位和64位皆適用的MyEclipse安裝教程

    這篇文章主要為大家詳細介紹了32位和64位皆適用的MyEclipse安裝教程,具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-10-10
  • Java生成與解析二維碼的完整指南

    Java生成與解析二維碼的完整指南

    二維碼是一種能夠將大量信息編碼在小空間的編碼器,它是一種由黑白方塊構成的圖片,可以將文本、鏈接、圖像等不同類型的信息編碼到其中,下面我們就來看看如何通過Java實現(xiàn)生成與解析二維碼吧
    2026-05-05
  • 詳解關于Spring Cloud 框架熱部署的方法

    詳解關于Spring Cloud 框架熱部署的方法

    本篇文章主要介紹了詳解關于Spring Cloud 框架熱部署的方法,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧
    2017-11-11

最新評論

孝感市| 环江| 年辖:市辖区| 聂荣县| 剑川县| 桂东县| 桐城市| 莱西市| 瓮安县| 华池县| 遂宁市| 通道| 泰顺县| 汶上县| 都江堰市| 平利县| 海淀区| 云龙县| 云龙县| 公主岭市| 太白县| 枣阳市| 乐清市| 光山县| 和顺县| 东源县| 惠来县| 类乌齐县| 绿春县| 临江市| 华容县| 南开区| 大理市| 磴口县| 丹江口市| 东阳市| 高邑县| 阿城市| 周口市| 西丰县| 监利县|