欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

SpringBean和Controller實(shí)現(xiàn)動(dòng)態(tài)注冊(cè)與注銷過(guò)程詳細(xì)講解

 更新時(shí)間:2023年02月09日 15:41:22   作者:小時(shí)候的陽(yáng)光  
這篇文章主要介紹了SpringBean和Controller實(shí)現(xiàn)動(dòng)態(tài)注冊(cè)與注銷過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)吧

部分場(chǎng)景下可能需要下載遠(yuǎn)程jar包,然后注冊(cè)jar包中的Bean和Controller

說(shuō)明

這里的Bean 一般特指 Service層的服務(wù)類,Controller本質(zhì)上也是Bean

注冊(cè)和注銷工具類

這里用了一些 hutool的工具類,hutools是一個(gè)不錯(cuò)的基礎(chǔ)工具集。

package cn.guzt.utils;
import cn.hutool.extra.spring.SpringUtil;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.DefaultListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.util.ClassUtils;
import org.springframework.util.ReflectionUtils;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;
import java.lang.reflect.Method;
/**
 * 動(dòng)態(tài)注冊(cè)注銷Spring Bean
 *
 * @author guzt
 */
@SuppressWarnings("unused")
public class DynamicRegistUtil {
    /**
     * 動(dòng)態(tài)注冊(cè)Bean
     *
     * @param beanName    bean名稱
     * @param targetClass bean對(duì)應(yīng)的類
     */
    public static void registerBeanDefinition(String beanName, Class<?> targetClass) {
        ApplicationContext applicationContext = SpringUtil.getApplicationContext();
        //獲取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory =
                (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        //創(chuàng)建bean信息.
        BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(targetClass);
        //動(dòng)態(tài)注冊(cè)bean.
        defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
    }
    /**
     * 動(dòng)態(tài)卸載Bean
     *
     * @param beanName bean名稱
     */
    public static void unRegisterBeanDefinition(String beanName) {
        ApplicationContext applicationContext = SpringUtil.getApplicationContext();
        if (!applicationContext.containsBean(beanName)) {
            return;
        }
        //獲取BeanFactory
        DefaultListableBeanFactory defaultListableBeanFactory =
                (DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
        defaultListableBeanFactory.removeBeanDefinition(beanName);
    }
    /**
     * 動(dòng)態(tài)注冊(cè)Controller
     *
     * @param controllerBeanName controller的beanName
     * @throws Exception 反射異常
     */
    public static void registerController(String controllerBeanName)
            throws Exception {
        final RequestMappingHandlerMapping requestMappingHandlerMapping =
                SpringUtil.getBean(RequestMappingHandlerMapping.class);
        if (requestMappingHandlerMapping != null) {
            Object controller = SpringUtil.getBean(controllerBeanName);
            if (controller == null) {
                return;
            }
            //注冊(cè)Controller
            Method method = requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().
                    getDeclaredMethod("detectHandlerMethods", Object.class);
            //將private改為可使用
            method.setAccessible(true);
            method.invoke(requestMappingHandlerMapping, controllerBeanName);
        }
    }
    /**
     * 動(dòng)態(tài)去掉Controller的Mapping
     *
     * @param controllerBeanName controller的beanName
     */
    public static void unregisterController(String controllerBeanName) {
        final RequestMappingHandlerMapping requestMappingHandlerMapping
                = SpringUtil.getBean("requestMappingHandlerMapping");
        if (requestMappingHandlerMapping != null) {
            Object controller = SpringUtil.getBean(controllerBeanName);
            if (controller == null) {
                return;
            }
            final Class<?> targetClass = controller.getClass();
            ReflectionUtils.doWithMethods(targetClass, method -> {
                Method specificMethod = ClassUtils.getMostSpecificMethod(method, targetClass);
                try {
                    Method createMappingMethod = RequestMappingHandlerMapping.class.
                            getDeclaredMethod("getMappingForMethod", Method.class, Class.class);
                    createMappingMethod.setAccessible(true);
                    RequestMappingInfo requestMappingInfo = (RequestMappingInfo)
                            createMappingMethod.invoke(requestMappingHandlerMapping, specificMethod, targetClass);
                    if (requestMappingInfo != null) {
                        requestMappingHandlerMapping.unregisterMapping(requestMappingInfo);
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }, ReflectionUtils.USER_DECLARED_METHODS);
        }
    }
}

編寫測(cè)試用例

創(chuàng)建一個(gè)maven項(xiàng)目(dynamic-regist-bean),里面主要引入spring-boot-starter-web即可

        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

創(chuàng)建一個(gè)service測(cè)試類

package org.example.service;
public interface DynamicRegistService {
    void serviceDo();
}

創(chuàng)建接口對(duì)應(yīng)的實(shí)現(xiàn)類,上面無(wú)需@Service 注解

package org.example.service.impl;
import lombok.extern.slf4j.Slf4j;
import org.example.service.DynamicRegistService;
@Slf4j
public class DynamicRegistServiceImpl implements DynamicRegistService {
    @Override
    public void serviceDo() {
        log.info("Spring動(dòng)態(tài)注冊(cè)的Bean dynamicRegistServiceImpl中的 serviceDo 無(wú)參方法執(zhí)行完成...");
    }
}

創(chuàng)建一個(gè)controller測(cè)試類,類上面無(wú)需 @Controller注解

package org.example.controller;
import org.springframework.web.bind.annotation.*;
import java.util.HashMap;
import java.util.Map;
@ResponseBody
@RequestMapping("dynamicRegistController")
public class DynamicRegistController {
    @PostMapping("postTest")
    public Map<String, Object> postTest(@RequestBody Map<String, Object> params) {
        Map<String, Object> map = new HashMap<>(4);
        map.put("code", "0");
        map.put("msg", "POST請(qǐng)求測(cè)試成功, 傳遞參數(shù)params:" + params.toString());
        map.put("data", "");
        return map;
    }
    @GetMapping("getTest/{id}")
    public Map<String, Object> getTest(@PathVariable("id") String id) {
        Map<String, Object> map = new HashMap<>(4);
        map.put("code", "0");
        map.put("msg", "GET請(qǐng)求測(cè)試成功, 傳輸?shù)膮?shù)id:" + id);
        map.put("data", "");
        return map;
    }
}

編譯打包

> maven clean package

mavne打包命令生成 dynamic-regist-bean.jar

另外一個(gè)SpringBoot中創(chuàng)建測(cè)試接口

假設(shè)訪問(wèn)BaseUrl為: http://localhost:8081

import cn.guzt.utils.DynamicRegistUtil;
import cn.hutool.core.util.ClassLoaderUtil;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.middol.starter.common.pojo.vo.NoBody;
import com.middol.starter.common.pojo.vo.ResponseVO;
import io.swagger.annotations.Api;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.io.File;
@Api(tags = "動(dòng)態(tài)注冊(cè)Bean、Controller測(cè)試")
@RestController
@RequestMapping("dynamicRegistTestController")
public class DynamicRegistTestController {
    private static final Logger logger = LoggerFactory.getLogger(DynamicRegistTestController.class);
    /**
     * 模擬從遠(yuǎn)程下載準(zhǔn)備要注冊(cè)Bean的jar文件
     *
     * @return jar文件
     */
    private File getRmoteJarFile() {
        return new File("E:/IDEA_HOME/dynamic-regist-bean/dynamic-regist-bean/target/dynamic-regist-bean.jar");
    }
    @GetMapping("registBean")
    public ResponseVO<NoBody> registBean() {
        File jarFile = getRmoteJarFile();
        // 準(zhǔn)備要注冊(cè)的Bean類名
        String className = "org.example.service.impl.DynamicRegistServiceImpl";
        // 準(zhǔn)備要注冊(cè)的Bean名稱
        String beanName = "dynamicRegistServiceImpl";
        // 注冊(cè)完成后調(diào)用Bean的測(cè)試方法
        String invokeMethod = "serviceDo";
        Class<?> targetClass = ClassLoaderUtil.loadClass(jarFile, className);
        logger.info("本次要注冊(cè)的bean className = {}", targetClass.getName());
        DynamicRegistUtil.registerBeanDefinition(beanName, targetClass);
        Object object = SpringUtil.getBean(beanName);
        ReflectUtil.invoke(object, invokeMethod);
        return ResponseVO.success();
    }
    @GetMapping("unRegistBean")
    public ResponseVO<NoBody> unRegistBean() {
        String beanName = "dynamicRegistServiceImpl";
        logger.info("本次要卸載的bean beanName = {}", beanName);
        DynamicRegistUtil.unRegisterBeanDefinition(beanName);
        logger.info("卸載結(jié)果:{}", SpringUtil.getApplicationContext().containsBean(beanName) ? "失敗" : "成功");
        return ResponseVO.success();
    }
    @GetMapping("registController")
    public ResponseVO<NoBody> registController() throws Exception {
        File jarFile = getRmoteJarFile();
        // 準(zhǔn)備要注冊(cè)的Bean類名
        String className = "org.example.controller.DynamicRegistController";
        // 準(zhǔn)備要注冊(cè)的Bean名稱
        String beanName = "dynamicRegistController";
        Class<?> targetClass = ClassLoaderUtil.loadClass(jarFile, className);
        logger.info("本次要注冊(cè)的controller className = {}", targetClass.getName());
        DynamicRegistUtil.registerBeanDefinition(beanName, targetClass);
        DynamicRegistUtil.registerController(beanName);
        return ResponseVO.success();
    }
    @GetMapping("unRegistController")
    public ResponseVO<NoBody> unRegistController() {
        String beanName = "dynamicRegistController";
        logger.info("本次要卸載的Controller beanName = {}", beanName);
        DynamicRegistUtil.unregisterController(beanName);
        DynamicRegistUtil.unRegisterBeanDefinition(beanName);
        logger.info("卸載結(jié)果:{}", SpringUtil.getApplicationContext().containsBean(beanName) ? "失敗" : "成功");
        return ResponseVO.success();
    }
}

測(cè)試結(jié)果

注冊(cè)Service

訪問(wèn): http://localhost:8081/dynamicRegistTestController/registBean

返回:

{"code":"0","message":"SUCCESS","data":null}

日志:

[http-nio-8081-exec-1] c.g.c.DynamicRegistTestController        : 本次要注冊(cè)的bean className = org.example.service.impl.DynamicRegistServiceImpl
[http-nio-8081-exec-1] o.e.s.impl.DynamicRegistServiceImpl      : Spring動(dòng)態(tài)注冊(cè)的Bean dynamicRegistServiceImpl中的 serviceDo 無(wú)參方法執(zhí)行完成...

注冊(cè)controller

訪問(wèn):http://localhost:8081/dynamicRegistTestController/registController

返回:

{"code":"0","message":"SUCCESS","data":null}

日志:

[http-nio-8081-exec-5] c.g.c.DynamicRegistTestController        : 本次要注冊(cè)的controller className = org.example.controller.DynamicRegistController

測(cè)試Controller 是否真的注冊(cè)成功:

訪問(wèn): http://localhost:8081/dynamicRegistController/getTest/aaaa 返回:

{"msg":"GET請(qǐng)求測(cè)試成功, 傳輸?shù)膮?shù)id:aaaa","data":"","code":"0"}

注銷Controller

訪問(wèn):http://localhost:8081/dynamicRegistTestController/unRegistController

然后重新訪問(wèn): http://localhost:8081/dynamicRegistController/getTest/aaaa

返回:404錯(cuò)誤 ,說(shuō)明注銷成功!

Whitelabel Error Page
This application has no explicit mapping for /error, so you are seeing this as a fallback.

Tue Feb 07 14:14:52 CST 2023
There was an unexpected error (type=Not Found, status=404).

到此這篇關(guān)于SpringBean和Controller實(shí)現(xiàn)動(dòng)態(tài)注冊(cè)與注銷過(guò)程詳細(xì)講解的文章就介紹到這了,更多相關(guān)SpringBean動(dòng)態(tài)注冊(cè)與注銷內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Java的Spring框架中實(shí)現(xiàn)發(fā)送郵件功能的核心代碼示例

    Java的Spring框架中實(shí)現(xiàn)發(fā)送郵件功能的核心代碼示例

    這篇文章主要介紹了Java的Spring框架中實(shí)現(xiàn)發(fā)送郵件功能的核心代碼示例,包括發(fā)送帶附件的郵件功能的實(shí)現(xiàn),需要的朋友可以參考下
    2016-03-03
  • JRebel2023.3 插件使用及安裝步驟詳解

    JRebel2023.3 插件使用及安裝步驟詳解

    JRebel是一款JVM插件,它使得Java代碼修改后不用重啟系統(tǒng),立即生效,IDEA上原生是不支持熱部署的,一般更新了 Java 文件后要手動(dòng)重啟 Tomcat 服務(wù)器,才能生效,浪費(fèi)時(shí)間浪費(fèi)生命,目前對(duì)于idea熱部署最好的解決方案就是安裝JRebel插件,本文分步驟介紹的非常詳細(xì),一起看看吧
    2023-08-08
  • 金三銀四復(fù)工高頻面試題java算法LeetCode396旋轉(zhuǎn)函數(shù)

    金三銀四復(fù)工高頻面試題java算法LeetCode396旋轉(zhuǎn)函數(shù)

    這篇文章主要為大家介紹了金三銀四復(fù)工高頻面試題之java算法題解LeetCode396旋轉(zhuǎn)函數(shù),有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2023-02-02
  • Fluent Mybatis實(shí)際開(kāi)發(fā)中的優(yōu)勢(shì)對(duì)比

    Fluent Mybatis實(shí)際開(kāi)發(fā)中的優(yōu)勢(shì)對(duì)比

    本文給大家介紹如何通過(guò)IQuery和IUpdate定義強(qiáng)大的動(dòng)態(tài)SQL語(yǔ)句,給大家分享Fluent Mybatis實(shí)際開(kāi)發(fā)中的優(yōu)勢(shì)講解,感興趣的朋友一起看看吧
    2021-08-08
  • Spring中@RabbitHandler和@RabbitListener的區(qū)別詳析

    Spring中@RabbitHandler和@RabbitListener的區(qū)別詳析

    @RabbitHandler是用于處理消息的方法注解,它與@RabbitListener注解一起使用,這篇文章主要給大家介紹了關(guān)于Spring中@RabbitHandler和@RabbitListener區(qū)別的相關(guān)資料,需要的朋友可以參考下
    2024-02-02
  • Java中URL傳中文時(shí)亂碼的解決方法

    Java中URL傳中文時(shí)亂碼的解決方法

    為什么說(shuō)亂碼是中國(guó)程序員無(wú)法避免的話題呢?這個(gè)主要是編碼機(jī)制上的原因,大家都知道中文和英文的編碼格式不一樣,解碼自然也不一樣!這篇文章就給大家分享了Java中URL傳中文時(shí)亂碼的解決方法,有需要的朋友們可以參考借鑒。
    2016-10-10
  • Java中JVM的雙親委派、內(nèi)存溢出、垃圾回收和調(diào)優(yōu)詳解

    Java中JVM的雙親委派、內(nèi)存溢出、垃圾回收和調(diào)優(yōu)詳解

    這篇文章主要介紹了Java中JVM的雙親委派、內(nèi)存溢出、垃圾回收和調(diào)優(yōu)詳解,類加載器是Java虛擬機(jī)(JVM)的一個(gè)重要組成部分,它的主要作用是將類的字節(jié)碼加載到內(nèi)存中,并生成對(duì)應(yīng)的Class對(duì)象,需要的朋友可以參考下
    2023-07-07
  • IntelliJ IDEA中使用mybatis-generator的示例

    IntelliJ IDEA中使用mybatis-generator的示例

    這篇文章主要介紹了IntelliJ IDEA中使用mybatis-generator,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2018-04-04
  • 解決Mybatis的@Param()注解導(dǎo)致分頁(yè)失效的問(wèn)題

    解決Mybatis的@Param()注解導(dǎo)致分頁(yè)失效的問(wèn)題

    這篇文章主要介紹了解決Mybatis的@Param()注解導(dǎo)致分頁(yè)失效的問(wèn)題,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下
    2021-04-04
  • 初識(shí)JAVA數(shù)組

    初識(shí)JAVA數(shù)組

    java語(yǔ)言中,數(shù)組是一種最簡(jiǎn)單的復(fù)合數(shù)據(jù)類型。數(shù)組是有序數(shù)據(jù)的集合,數(shù)組中的每個(gè)元素具有相同的數(shù)據(jù)類型,可以用一個(gè)統(tǒng)一的數(shù)組名和下標(biāo)來(lái)唯一地確定數(shù)組中的元素。數(shù)組有一維數(shù)組和多維數(shù)組。
    2014-08-08

最新評(píng)論