首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如果AppContext初始化失败,则正确终止Spring和Tomcat

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

Stack Overflow用户
提问于 2018-03-06 16:01:31
回答 1查看 3.2K关注 0票数 4

当我在嵌入式Tomcat上启动Spring应用程序时,一些东西在启动期间失败(例如,没有到DB或Liquibase更新失败的连接,或者找到循环依赖,等等),Tomcat继续监听8080端口。

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

  1. 这是否是预期的行为( Tomcat应该继续监听)?
  2. 如何在应用程序上下文初始化失败时停止Spring和Tomcat?

下面是日志的示例:

代码语言:javascript
复制
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:

代码语言:javascript
复制
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

依赖关系:

代码语言:javascript
复制
<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>

UPD 2

Application.java:

代码语言:javascript
复制
@SpringBootApplication
@EnableJpaRepositories(basePackages = "com.test")
@EnableCaching
@EnableScheduling
public class Application extends SpringBootServletInitializer {

    public Application() {
    }

    public static void main(final String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-03-13 07:06:18

其中可能有两种情况

第一种情况

应用程序已经启动并运行,App被创建,然后在服务器中出现一些运行时异常,您希望完成一个优雅的关闭。在这个场景中,您可以使用像弹簧启动优美停机这样的实用程序

设想2:

这是当Spring无法创建应用程序上下文本身时发生的场景。您的场景属于这一类别。当应用程序启动时,它尝试将配置与application.properties连接起来,如果有任何问题,应用程序上下文本身将不会被创建。

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

代码语言:javascript
复制
       try{
           SpringApplication.run(Application.class, args).close();;
        }
        catch(Exception ex){
            System.out.println("Going to exit");
            System.exit(-1);
        }

在此之后,Tomcat实例将无法运行,并且端口将可用

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/49135156

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档