You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何通过按钮启停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端点实现
    1. 在Spring Boot项目的pom.xml中引入Actuator依赖:
      <dependency>
          <groupId>org.springframework.boot</groupId>
          <artifactId>spring-boot-starter-actuator</artifactId>
      </dependency>
      
    2. 在application.yml中配置开启shutdown端点并允许外部调用:
      management:
        endpoints:
          web:
            exposure:
              include: shutdown
        endpoint:
          shutdown:
            enabled: true
      
    3. 本地程序通过HTTP POST请求调用http://localhost:你的应用端口/actuator/shutdown,即可触发优雅关闭。
  • 方案二(强制关闭):直接调用之前保存的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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 11:27:11