如何通过按钮启停Spring Boot并获取控制器等Bean实例数据?
实现方案
一、本地程序控制Spring Boot的构建、启动与关闭
1. 触发构建与启动
- 构建逻辑:直接调用Maven/Gradle命令行工具完成构建,比如Maven用
mvn clean package,本地程序通过ProcessBuilder执行该命令,同时监听命令输出,将进度反馈到UI。 - 启动逻辑:构建完成后,执行
java -jar 你的jar包路径.jar命令,同样用ProcessBuilder启动进程,务必保存Process实例,为后续关闭操作做准备。 - 按钮绑定:将构建、启动逻辑绑定到按钮点击事件,注意用异步线程执行命令,避免阻塞UI界面。
2. 彻底关闭Spring Boot应用
有两种方案可选,优先推荐优雅关闭:
- 方案一(优雅关闭):借助Spring Boot Actuator的
shutdown端点实现- 在Spring Boot项目的
pom.xml中引入Actuator依赖:<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> - 在
application.yml中配置开启shutdown端点并允许外部调用:management: endpoints: web: exposure: include: shutdown endpoint: shutdown: enabled: true - 本地程序通过HTTP POST请求调用
http://localhost:你的应用端口/actuator/shutdown,即可触发优雅关闭。
- 在Spring Boot项目的
- 方案二(强制关闭):直接调用之前保存的
Process.destroy()方法终止进程,但这种方式可能导致资源未正常释放,仅作为备选。
二、获取Spring注解类实例并监听数据
1. 收集Spring注解类实例
在Spring Boot应用中实现ApplicationListener<ContextRefreshedEvent>,当Spring容器初始化完成后,自动收集所有带指定注解的Bean实例:
@Component public class AnnotatedBeanCollector implements ApplicationListener<ContextRefreshedEvent> { private final Map<Class<?>, Object> collectedBeans = new ConcurrentHashMap<>(); @Override public void onApplicationEvent(ContextRefreshedEvent event) { ApplicationContext context = event.getApplicationContext(); // 收集所有@RestController注解的Bean Map<String, Object> controllers = context.getBeansWithAnnotation(RestController.class); controllers.values().forEach(bean -> collectedBeans.put(bean.getClass(), bean)); // 可扩展收集其他注解类,比如@Service、@Component等 } public Map<Class<?>, Object> getCollectedBeans() { return collectedBeans; } }
2. 监听并传输数据到本地程序
可以通过AOP切面拦截控制器方法,捕获请求和响应数据,再传输到本地程序:
@Aspect @Component public class ControllerDataMonitor { @Around("@annotation(org.springframework.web.bind.annotation.PostMapping) || @annotation(org.springframework.web.bind.annotation.GetMapping)") public Object interceptControllerMethod(ProceedingJoinPoint joinPoint) throws Throwable { // 获取请求参数 Object[] requestParams = joinPoint.getArgs(); // 执行原方法获取返回结果 Object responseResult = joinPoint.proceed(); // 获取当前方法所属的控制器类 Class<?> controllerClass = joinPoint.getTarget().getClass(); // 将数据发送到本地程序,可通过Socket、HTTP请求等方式实现 sendDataToLocalApp(controllerClass, requestParams, responseResult); return responseResult; } private void sendDataToLocalApp(Class<?> controllerClass, Object[] requestParams, Object responseResult) { // 实现数据传输逻辑,比如用Socket客户端发送数据到本地程序的服务端 } }
3. 本地程序接收并展示数据
本地程序启动一个Socket服务端或者HTTP接口,接收Spring Boot应用发送的数据,然后将数据解析后展示在UI界面上即可。
内容的提问来源于stack exchange,提问作者user29983345
相关产品推荐
相关产品推荐

