Python 官方文档:入门教程 => 点击学习
目录说明注册和注销工具类编写测试用例测试结果注册Service注册controller注销Controller部分场景下可能需要下载远程jar包,然后注册jar包中的Bean和Con
部分场景下可能需要下载远程jar包,然后注册jar包中的Bean和Controller
这里的Bean 一般特指 Service层的服务类,Controller本质上也是Bean
这里用了一些 hutool的工具类,hutools是一个不错的基础工具集。
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;
@SuppressWarnings("unused")
public class DynamicReGIStUtil {
public static void registerBeanDefinition(String beanName, Class<?> targetClass) {
ApplicationContext applicationContext = SpringUtil.getApplicationContext();
//获取BeanFactory
DefaultListableBeanFactory defaultListableBeanFactory =
(DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
//创建bean信息.
BeanDefinitionBuilder beanDefinitionBuilder = BeanDefinitionBuilder.genericBeanDefinition(targetClass);
//动态注册bean.
defaultListableBeanFactory.registerBeanDefinition(beanName, beanDefinitionBuilder.getBeanDefinition());
}
public static void unRegisterBeanDefinition(String beanName) {
ApplicationContext applicationContext = SpringUtil.getApplicationContext();
if (!applicationContext.containsBean(beanName)) {
return;
}
//获取BeanFactory
DefaultListableBeanFactory defaultListableBeanFactory =
(DefaultListableBeanFactory) applicationContext.getAutowireCapableBeanFactory();
defaultListableBeanFactory.removeBeanDefinition(beanName);
}
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;
}
//注册Controller
Method method = requestMappingHandlerMapping.getClass().getSuperclass().getSuperclass().
getDeclaredMethod("detectHandlerMethods", Object.class);
//将private改为可使用
method.setAccessible(true);
method.invoke(requestMappingHandlerMapping, controllerBeanName);
}
}
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);
}
}
}
创建一个Maven项目(dynamic-regist-bean),里面主要引入spring-boot-starter-web即可
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
创建一个service测试类
package org.example.service;
public interface DynamicRegistService {
void serviceDo();
}
创建接口对应的实现类,上面无需@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动态注册的Bean dynamicRegistServiceImpl中的 serviceDo 无参方法执行完成...");
}
}
创建一个controller测试类,类上面无需 @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请求测试成功, 传递参数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请求测试成功, 传输的参数id:" + id);
map.put("data", "");
return map;
}
}
编译打包
> maven clean package
mavne打包命令生成 dynamic-regist-bean.jar
另外一个SpringBoot中创建测试接口
假设访问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 = "动态注册Bean、Controller测试")
@RestController
@RequestMapping("dynamicRegistTestController")
public class DynamicRegistTestController {
private static final Logger logger = LoggerFactory.getLogger(DynamicRegistTestController.class);
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();
// 准备要注册的Bean类名
String className = "org.example.service.impl.DynamicRegistServiceImpl";
// 准备要注册的Bean名称
String beanName = "dynamicRegistServiceImpl";
// 注册完成后调用Bean的测试方法
String invokeMethod = "serviceDo";
Class<?> targetClass = ClassLoaderUtil.loadClass(jarFile, className);
logger.info("本次要注册的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("卸载结果:{}", SpringUtil.getApplicationContext().containsBean(beanName) ? "失败" : "成功");
return ResponseVO.success();
}
@GetMapping("registController")
public ResponseVO<NoBody> registController() throws Exception {
File jarFile = getRmoteJarFile();
// 准备要注册的Bean类名
String className = "org.example.controller.DynamicRegistController";
// 准备要注册的Bean名称
String beanName = "dynamicRegistController";
Class<?> targetClass = ClassLoaderUtil.loadClass(jarFile, className);
logger.info("本次要注册的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("卸载结果:{}", SpringUtil.getApplicationContext().containsBean(beanName) ? "失败" : "成功");
return ResponseVO.success();
}
}
访问: http://localhost:8081/dynamicRegistTestController/registBean
返回:
{"code":"0","message":"SUCCESS","data":null}
日志:
[http-NIO-8081-exec-1] c.g.c.DynamicRegistTestController : 本次要注册的bean className = org.example.service.impl.DynamicRegistServiceImpl
[http-nio-8081-exec-1] o.e.s.impl.DynamicRegistServiceImpl : Spring动态注册的Bean dynamicRegistServiceImpl中的 serviceDo 无参方法执行完成...
访问:http://localhost:8081/dynamicRegistTestController/registController
返回:
{"code":"0","message":"SUCCESS","data":null}
日志:
[http-nio-8081-exec-5] c.g.c.DynamicRegistTestController : 本次要注册的controller className = org.example.controller.DynamicRegistController
测试Controller 是否真的注册成功:
访问: http://localhost:8081/dynamicRegistController/getTest/aaaa 返回:
{"msg":"GET请求测试成功, 传输的参数id:aaaa","data":"","code":"0"}
访问:http://localhost:8081/dynamicRegistTestController/unRegistController
然后重新访问: http://localhost:8081/dynamicRegistController/getTest/aaaa
返回:404错误 ,说明注销成功!
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).
到此这篇关于SpringBean和Controller实现动态注册与注销过程详细讲解的文章就介绍到这了,更多相关SpringBean动态注册与注销内容请搜索编程网以前的文章或继续浏览下面的相关文章希望大家以后多多支持编程网!
--结束END--
本文标题: SpringBean和Controller实现动态注册与注销过程详细讲解
本文链接: https://lsjlt.com/news/195413.html(转载时请注明来源链接)
有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341
2024-03-01
2024-03-01
2024-03-01
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
2024-02-29
回答
回答
回答
回答
回答
回答
回答
回答
回答
回答
0