简体   繁体   中英

How starter-web prevent spring-boot exit?

When using spring-boot-starter-web, The spring-boot application won't exit after startup.

And with Jetbrain IDEA, There is an icon show spring-boot start up finished:

在此处输入图像描述

在此处输入图像描述

But if I using :

public static void main ( String[] args ){
    SpringApplication.run(Application.class, args);
    Thread.sleep(Long.MAX_VALUE);
}

Or

public class MyRunner implements ApplicationRunner{
    public void run() {
        Thread.sleep(Long.MAX_VALUE);
    }
}

Can let spring-boot keep running but the IDEA icon will loading forever, So that must be different way compare with starter-web.

Update1: And those two method will cause SpringBootTest wait forever

Question: What's the code that spring-boot-starter-web prevent spring-boot exit ?

I don't know, what is a reason, but without webserver, you can prevent shutdown only if any other thread still active (non-daemon thread). Infinite loop in another thread will prevent program exit.

package com.example.demo;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;

@SpringBootApplication
public class DemoApplication {

    public static void main(String[] args) {
        System.out.println("main started");
        new Thread(() -> {
            System.out.println("thread started");
            ConfigurableApplicationContext context = SpringApplication.run(DemoApplication.class, args);
            while (true) {
                System.out.println(context);
                try {
                    Thread.sleep(1000L);
                } catch (InterruptedException e) {
                }
            }
        }).start();
        System.out.println("main finished");
    }



}

output example

    main started
    main finished
    thread started

    .   ____          _            __ _ _
    /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
    ( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
    \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
    '  |____| .__|_| |_|_| |_\__, | / / / /
    =========|_|==============|___/=/_/_/_/
    :: Spring Boot ::                (v2.6.7)

    2022-06-24 22:34:31.648  INFO 8084 --- [       Thread-1] o.s.boot.SpringApplication               : Starting application using Java 1.8.0_312 on DESKTOP with PID 8084 (started by user in C:\Users\user\IdeaProjects\demo)
    2022-06-24 22:34:31.650  INFO 8084 --- [       Thread-1] o.s.boot.SpringApplication               : No active profile set, falling back to 1 default profile: "default"
    2022-06-24 22:34:31.985  INFO 8084 --- [       Thread-1] org.quartz.impl.StdSchedulerFactory      : Using default implementation for ThreadExecutor
    2022-06-24 22:34:31.991  INFO 8084 --- [       Thread-1] org.quartz.core.SchedulerSignalerImpl    : Initialized Scheduler Signaller of type: class org.quartz.core.SchedulerSignalerImpl
    2022-06-24 22:34:31.991  INFO 8084 --- [       Thread-1] org.quartz.core.QuartzScheduler          : Quartz Scheduler v.2.3.2 created.
    2022-06-24 22:34:31.991  INFO 8084 --- [       Thread-1] org.quartz.simpl.RAMJobStore             : RAMJobStore initialized.
    2022-06-24 22:34:31.992  INFO 8084 --- [       Thread-1] org.quartz.core.QuartzScheduler          : Scheduler meta-data: Quartz Scheduler (v2.3.2) 'quartzScheduler' with instanceId 'NON_CLUSTERED'
    Scheduler class: 'org.quartz.core.QuartzScheduler' - running locally.
    NOT STARTED.
    Currently in standby mode.
    Number of jobs executed: 0
    Using thread pool 'org.quartz.simpl.SimpleThreadPool' - with 10 threads.
    Using job-store 'org.quartz.simpl.RAMJobStore' - which does not support persistence. and is not clustered.

    2022-06-24 22:34:31.992  INFO 8084 --- [       Thread-1] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler 'quartzScheduler' initialized from an externally provided properties instance.
    2022-06-24 22:34:31.992  INFO 8084 --- [       Thread-1] org.quartz.impl.StdSchedulerFactory      : Quartz scheduler version: 2.3.2
    2022-06-24 22:34:31.992  INFO 8084 --- [       Thread-1] org.quartz.core.QuartzScheduler          : JobFactory set to: org.springframework.scheduling.quartz.SpringBeanJobFactory@501627dc
    2022-06-24 22:34:32.009  INFO 8084 --- [       Thread-1] o.s.s.quartz.SchedulerFactoryBean        : Starting Quartz Scheduler now
    2022-06-24 22:34:32.010  INFO 8084 --- [       Thread-1] org.quartz.core.QuartzScheduler          : Scheduler quartzScheduler_$_NON_CLUSTERED started.
    2022-06-24 22:34:32.015  INFO 8084 --- [       Thread-1] o.s.boot.SpringApplication               : Started application in 0.601 seconds (JVM running for 1.051)
    org.springframework.context.annotation.AnnotationConfigApplicationContext@74ed4e3, started on Fri Jun 24 22:34:31 MSK 2022
    org.springframework.context.annotation.AnnotationConfigApplicationContext@74ed4e3, started on Fri Jun 24 22:34:31 MSK 2022
    org.springframework.context.annotation.AnnotationConfigApplicationContext@74ed4e3, started on Fri Jun 24 22:34:31 MSK 2022
and so on...

only 1 dependency (just random starter, not web, quartz not required here)

org.springframework.boot:spring-boot-starter-quartz

just infinite loop in non-daemon thread ...

To answer the question

What's the code that spring-boot-starter-web prevent spring-boot exit

spring-boot-web creates web server beans, that use non-daemon listener threads (as you want them to be alive and running to waiting for incoming connections and handle them).

This makes your code reach end of your main method, however JVM does not exit, as it has non-daemon threads running.

If you want to keep your application alive, you'd need to do the same - the simplest way would be to eg create a Thread in a bean like @Slongtong has suggested.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM