在springboot应用程序启动线程

29 java spring spring-boot

我想在spring启动后执行一个java类(包含我想要执行的java线程).我的初始代码:

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
Run Code Online (Sandbox Code Playgroud)

这是我想在开始时执行的代码:

public class SimularProfesor implements Runnable{

    // Class atributes

    // Constructor
    public SimularProfesor() {
        //Initialization of atributes
    }

    @Override
    public void run() {
        while(true) {
            // Do something
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我怎么称呼这个帖子?这就是我应该做的:

@SpringBootApplication
public class Application {
     public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
        // Call thread (constructor must be executed too)
     }
}
Run Code Online (Sandbox Code Playgroud)

M. *_*num 38

不要自己乱用线程.Spring(也是普通的Java)有一个很好的抽象.

首先TaskExecutor在配置中创建该类型的bean

@Bean
public TaskExecutor taskExecutor() {
    return new SimpleAsyncTaskExecutor(); // Or use another one of your liking
}
Run Code Online (Sandbox Code Playgroud)

然后创建一个CommandLineRunner(虽然ApplicationListener<ContextRefreshedEvent>也会工作)来安排你的任务.

@Bean
public CommandLineRunner schedulingRunner(TaskExecutor executor) {
    return new CommandLineRunner() {
        public void run(String... args) throws Exception {
            executor.execute(new SimularProfesor());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,您也可以在春季管理自己的班级.

这样做的好处是Spring也会为你清理线程,你不必自己考虑它.我在CommandLineRunner这里使用了一个,因为这将在所有bean初始化bean之后执行.

  • 如果我们需要将依赖项注入Runnable类怎么办? (2认同)

小智 5

  • 主类 SpringBoot

    @SpringBootApplication
    @EnableAsync
    @Controller
    public class ...
    
    
    Run Code Online (Sandbox Code Playgroud)
  • 示例类控制器

    import javax.annotation.PostConstruct;
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.ApplicationContext;
    import org.springframework.core.task.TaskExecutor;
    import org.springframework.stereotype.Component;
    
    @Component
    public class ExecutorBase {
    
        private static final Logger log = LoggerFactory.getLogger(ExecutorBase.class);
    
        @Autowired
        private TaskExecutor taskExecutor;
        @Autowired
        private ApplicationContext applicationContext;
    
        private Boolean debug = true;
    
        @PostConstruct
        public void atStartup() {
            ClasseTaskRunn classeTaskRunn = applicationContext.getBean(ClasseTaskRunn.class);
            taskExecutor.execute(classeTaskRunn );
            if (debug) {
                log.warn("###### Startup ok");
            }
        }
    }
    
    
    Run Code Online (Sandbox Code Playgroud)
  • 示例类任务可运行

    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.context.annotation.Scope;
    import org.springframework.stereotype.Component;
    
    @Component
    @Scope("application")
    public class ClasseTaskRunn implements Runnable {
    
        private static final Logger log = LoggerFactory.getLogger(ClasseTaskRunn.class);
    
        @Autowired
        ClasseDAO classeDAO;
    
        @Override
        public void run() {
            longBackgorund();
        }
    
        protected void longBackgorund() {
            while (test) {
                if (debug) {
                    log.warn("###### DEBUG: " ... );
                }
    
                try {
                    Thread.sleep(10000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }
    
    
    Run Code Online (Sandbox Code Playgroud)

  • 如果你想在 Spring 上下文初始化后运行线程,你可以使用 @EventListener(ApplicationReadyEvent.class) 注解而不是 @PostConstruct (2认同)