有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用LifecycleProcessor和启动信号(在@SpringBootApplication中使用@Autowire)

我有一个基于Spring Boot的简单应用程序

在本例中,我不使用任何XML配置

主要组件是appMain(使用隐式构造函数自动连接),它依赖于实现LifecycleProcessordataCollector。它重写并定义了public void start(),我希望在创建Spring容器之后立即调用它

根据文件:

任何Spring托管对象都可以实现该接口。然后,当ApplicationContext本身接收到启动和停止信号时(例如,对于运行时的停止/重新启动场景),它会将这些调用级联到该上下文中定义的所有生命周期实现

但是这个start方法从未被调用。那么start signal是否需要明确定义并发送到ApplicationContext?它不是总是在容器启动时完成的吗?我认为这是容器生命周期的一部分,但似乎不是这样。那怎么办呢

我需要一些类似于deamon的并行线程,它可以在整个应用程序中启动和停止。这个生命周期处理器是我应该使用的还是春天有更好的选择

AppMain

import org.springframework.boot.Banner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.DependsOn;
import javax.annotation.PostConstruct;

@SpringBootApplication
@DependsOn("dataCollector")
public class AppMain {

    public LocColMain(ConfigurableApplicationContext context) {
        this.context = context;
    }

    @PostConstruct
    private void init() {
        context.registerShutdownHook();
    }

    public static void main(String[] args) {
        SpringApplication app = new SpringApplication(AppMain.class);
        app.setBannerMode(Banner.Mode.OFF);
        app.run(args);
    }
}

数据采集器

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.LifecycleProcessor;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import java.sql.Timestamp;
import java.util.Random;

@Component
public class DataCollector implements LifecycleProcessor {
    private static final Logger log = LoggerFactory.getLogger(DataCollector.class);

    private boolean isRunning;

    private final DaoRssiCache daoRssiCache;

    public DataCollector(DaoRssiCache daoRssiCache) {
        this.daoRssiCache = daoRssiCache;
    }

    @Override
    public void onRefresh() {
        log.info("Data collector - REFRESH.");
    }

    @Override
    public void onClose() {
        log.info("Data collector - CLOSE.");

        stop();
    }

    @PreDestroy
    public void destroy() {
        log.info("Data collector - DESTROY.");

        stop();
    }

    @PostConstruct
    public void init() {
        log.info("Data collector - CREATED.");
    }

    @Override
    public void start() {
        log.info("Data collector - START.");

        isRunning = true;

        while (isRunning) {
            // TODO: do some business stuff...
        }
    }

    @Override
    public void stop() {
        log.info("Data collector - STOP.");
        isRunning = false;
    }

    @Override
    public boolean isRunning() {
        return isRunning;
    }
}

共 (1) 个答案

  1. # 1 楼答案

    若您需要后台作业的并行线程,那个么您应该创建它。根据您的要求,线程可以是daemon。如果您不需要等待线程完成其工作,您可以将其指定为deamon,并且在关闭应用程序后-此线程将被中断而不超时

    例如:

    class BackgroundJob extends Thread {
        public BackgroundJob(boolean daemon) {
            setDaemon(daemon);
        }
        //others logic
    }