Java 如果AppContext初始化失败,则正确终止Spring引导和Tomcat

Java 如果AppContext初始化失败,则正确终止Spring引导和Tomcat,java,spring,tomcat,spring-boot,Java,Spring,Tomcat,Spring Boot,当我在嵌入式Tomcat上启动Spring引导应用程序时,在启动过程中出现了一些故障(例如,没有连接到DB或Liquibase更新失败,或者发现了循环依赖项等),Tomcat继续在8080端口上侦听 如果我向某个端点发送HTTP请求,应用程序将返回404NotFound 这是预期的行为(Tomcat是否应该继续侦听) 当应用程序上下文初始化失败时,如何停止Spring引导和Tomcat 下面是日志的示例: org.springframework.context.ApplicationContex

当我在嵌入式Tomcat上启动Spring引导应用程序时,在启动过程中出现了一些故障(例如,没有连接到DB或Liquibase更新失败,或者发现了循环依赖项等),Tomcat继续在8080端口上侦听

如果我向某个端点发送HTTP请求,应用程序将返回404NotFound

  • 这是预期的行为(Tomcat是否应该继续侦听)
  • 当应用程序上下文初始化失败时,如何停止Spring引导和Tomcat
  • 下面是日志的示例:

    org.springframework.context.ApplicationContextException: Unable to start embedded container; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'tomcatEmbeddedServletContainerFactory' defined in class path resource [org/springframework/boot/autoconfigure/web/EmbeddedServletContainerAutoConfiguration$EmbeddedTomcat.class]: Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serverProperties' defined in class path resource [org/springframework/boot/autoconfigure/web/ServerPropertiesAutoConfiguration.class]: Initialization of bean failed; nested exception is javax.validation.ValidationException: Unable to instantiate Configuration.
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.onRefresh(EmbeddedWebApplicationContext.java:137)
        at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:536)
        at org.springframework.boot.context.embedded.EmbeddedWebApplicationContext.refresh(EmbeddedWebApplicationContext.java:122)
        at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:693)
        at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:360)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:303)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1118)
        at org.springframework.boot.SpringApplication.run(SpringApplication.java:1107)
        at com.test.Application.main(Application.java:33)
    
    在此异常之后,Tomcat在指定端口上仍然可用

    UPD

    application.properties:

    spring.profiles.default=production
    spring.application.name=test
    
    spring.datasource.url=jdbc:postgresql://localhost:5432/testdb
    spring.datasource.username=test
    spring.datasource.password=test123
    spring.jpa.properties.hibernate.dialect=org.hibernate.dialect.PostgreSQLDialect
    
    spring.jpa.hibernate.ddl-auto=none
    
    liquibase.change-log=classpath:/liquibase/changelog.xml
    
    依赖项:

    <properties>
        <spring.boot.version>1.5.9.RELEASE</spring.boot.version>
    
        <liquibase.version>3.5.3</liquibase.version>
        <postgresql.version>9.4-1201-jdbc41</postgresql.version>
        <hsqldb.version>2.4.0</hsqldb.version>
    
        <powermock.version>1.7.3</powermock.version>
    </properties>
    
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
            <version>${spring.boot.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat.embed</groupId>
                    <artifactId>tomcat-embed-el</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-annotations-api</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
            <version>${spring.boot.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.apache.tomcat</groupId>
                    <artifactId>tomcat-juli</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
            <version>${spring.boot.version}</version>
            <exclusions>
                <exclusion>
                    <groupId>org.codehaus.groovy</groupId>
                    <artifactId>groovy</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>nz.net.ultraq.thymeleaf</groupId>
                    <artifactId>thymeleaf-layout-dialect</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-autoconfigure</artifactId>
            <version>${spring.boot.version}</version>
            <scope>compile</scope>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <version>${spring.boot.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-test</artifactId>
            <version>4.3.14.RELEASE</version>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>org.postgresql</groupId>
            <artifactId>postgresql</artifactId>
            <version>${postgresql.version}</version>
        </dependency>
    
        <dependency>
            <groupId>org.liquibase</groupId>
            <artifactId>liquibase-core</artifactId>
            <version>${liquibase.version}</version>
            <scope>compile</scope>
        </dependency>
    
        <dependency>
            <groupId>org.hsqldb</groupId>
            <artifactId>hsqldb</artifactId>
            <version>${hsqldb.version}</version>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-module-junit4</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>org.powermock</groupId>
            <artifactId>powermock-api-mockito</artifactId>
            <version>${powermock.version}</version>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-library</artifactId>
            <version>${hamcrest.version}</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-core</artifactId>
            <version>${hamcrest.version}</version>
            <scope>test</scope>
        </dependency>
    
        <dependency>
            <groupId>com.google.code.simple-spring-memcached</groupId>
            <artifactId>spring-cache</artifactId>
            <version>3.6.1</version>
            <exclusions>
                <exclusion>
                    <groupId>org.hamcrest</groupId>
                    <artifactId>hamcrest-core</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>commons-collections</groupId>
                    <artifactId>commons-collections</artifactId>
                </exclusion>
                <exclusion>
                    <groupId>junit</groupId>
                    <artifactId>junit</artifactId>
                </exclusion>
            </exclusions>
        </dependency>
    
        <dependency>
            <groupId>org.codehaus.janino</groupId>
            <artifactId>janino</artifactId>
            <version>3.0.8</version>
        </dependency>
    
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-classic</artifactId>
            <version>1.2.3</version>
        </dependency>
    
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
            <version>1.2.3</version>
        </dependency>
    </dependencies>
    
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
    

    在这种情况下可能有两种情况

    第一种情况

    应用程序已启动并正在运行,应用程序上下文已创建,然后服务器中出现一些运行时异常,您希望正常关机。在这个场景中,您可以使用如下实用程序

    情景2:

    当Spring Boot无法创建应用程序上下文本身时,就会出现这种情况。您的场景属于这一类。当应用程序启动时,它尝试从application.properties连接配置,如果有任何问题,将不会创建应用程序上下文本身

    因此,在这个场景中,您不能选择正常关闭,因为您没有应用程序上下文的实例。在这种情况下,您可以捕获异常,选择适当的日志记录并手动执行系统退出

           try{
               SpringApplication.run(Application.class, args).close();;
            }
            catch(Exception ex){
                System.out.println("Going to exit");
                System.exit(-1);
            }
    

    在此之后,Tomcat实例将不会运行,端口将可用

    请共享您的配置文件&pom。xml@Bond-JavaBond doneAlso请分享
    应用程序。java
    @Bond JavaBond done。在Application.javaHi中没有什么特别之处。在依赖项中添加“spring boot starter tomcat”和插件“spring boot maven plugin”。使用返回“return Application.sources(Application.class);”覆盖应用程序类中的configure方法,这将修复配置初始化。排除tomcat注释api有什么原因吗?看起来第二个场景中的try/catch解决了这个问题。非常感谢。很难找到这些信息。我还遇到了第二种情况,出现了BeanCreationException,我的应用程序一直在运行。我认为它应该失败并默认停止,也许在某个地方仍然存在问题,但这个解决方案确实帮助我至少停止了应用程序。
           try{
               SpringApplication.run(Application.class, args).close();;
            }
            catch(Exception ex){
                System.out.println("Going to exit");
                System.exit(-1);
            }