Spring @PreDestroy:没有记录,因为Logback过早停止

Har*_*dev 8 java spring logback logback-classic

在我的项目中,我使用Logback作为日志工具.我有以下课程

@Component
class Test {
    @PreDestroy
    public void destroy() {
        try {
            ...
        } catch (Exception e) {
            LoggerFactory.getLogger(getClass()).error(e.getLocalizedMessage(), e);
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

现在,我取消部署servlet.发生异常时,Logback不会打印消息和堆栈跟踪.这是因为Logback在destroy()Spring调用之前正在清理.取消部署servlet时,这是第一个(也是最后一个)日志行:

15:46:19,084 |-INFO in ch.qos.logback.classic.servlet.LogbackServletContextListener@7957fe56 - About to stop ch.qos.logback.classic.LoggerContext [default]
Run Code Online (Sandbox Code Playgroud)

我通过添加a System.out.println("...");来验证Logback是否先停止destroy().

有没有什么办法解决这一问题?

我的依赖:

<dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>org.springframework</groupId>
            <artifactId>spring-framework-bom</artifactId>
            <version>5.0.1.RELEASE</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>
        <dependency>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
            <version>99-empty</version>
        </dependency>
    </dependencies>
</dependencyManagement>

<dependencies>
    <dependency>
        <groupId>commons-logging</groupId>
        <artifactId>commons-logging</artifactId>
    </dependency>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.25</version>
    </dependency>
    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-core</artifactId>
        <version>1.2.3</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-access</artifactId>
        <version>1.2.3</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-core</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-jcl</artifactId>
    </dependency>
</dependencies>
Run Code Online (Sandbox Code Playgroud)

请注意,spring-jcl用于路由commons-loggingslf4j(将路由到logback).我没用jcl-over-slf4j.

Dov*_*vmo 5

有一种记录的方法可以禁用以禁用注册LogbackServletContextListener:

您可以通过在Web应用程序的web.xml文件中设置命名的log​​backDisableServletContainerInitializer来禁用自动安装LogbackServletContextListener.这是相关的片段.

<web-app>
    <context-param>
        <param-name>logbackDisableServletContainerInitializer</param-name>
        <param-value>true</param-value>
    </context-param>
    .... 
</web-app>
Run Code Online (Sandbox Code Playgroud)

请注意,logbackDisableServletContainerInitializer变量也可以设置为Java系统属性和OS环境变量.最本地的设置具有优先级,即web-app first,system property second和OS environment last.

我想你可能想要编写自己的关闭钩子,如果是这种情况并停止LoggerContext