Java 구성을 사용하고 XML 구성을 사용하지 않고 구성 할 때 Tomcat에서 실행되는 간단한 Spring 5.1.12 웹 응용 프로그램이 Lifecycle.stop () 메서드를 호출하는 이유를 알 수 없습니다. SmartLifecycle을 구현하는 LifecycleLoggingBean 빈이 있으며 모든 메서드를 재정의했습니다 (질문 끝 참조).
업데이트 : mvc-servlet.xml에서 LifecycleLoggingBean을 인스턴스화하면 stop이 호출됩니다. 기본적으로 기본 응용 프로그램 컨텍스트를 중지하는 것은 없습니다. 메인 애플리케이션 컨텍스트에서 닫기를 트리거하는 "올바른"방법이 있습니까? 결과적으로 메인 애플리케이션 컨텍스트에서도 호출되며 로그되지 않습니다.
이렇게 앱을 구성하면 Lifecycle.stop ()이 호출됩니다.
@EnableWebMvc
@Configuration
@ComponentScan({"some.package"})
public class SpringConfig implements WebMvcConfigurer {
@Bean
public InternalResourceViewResolver viewResolver() {
InternalResourceViewResolver viewResolver
= new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("/WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
}
해당 클래스를 제거하고 대신 web.xml에 다음을 넣으면 :
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>mvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>2</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
그리고 applicationContext.xml에 다음이 있습니다.
<context:component-scan base-package="some.package" />
<mvc:annotation-driven />
<bean class = "org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name = "prefix" value = "/WEB-INF/jsp/"/>
<property name = "suffix" value = ".jsp"/>
</bean>
mvc-servlet.xml을 추가하십시오.
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
">
</beans>
그러면 Lifecycle.stop ()이 호출되지 않습니다.
모든 경우에 Lifecycle.start ()가 호출됩니다.
다음은 Java 구성이있는 로그입니다.
[org.springframework.web.servlet.DispatcherServlet]:525 - - Initializing Servlet 'dispatcher'
[some.packge.testapp.LifecycleLoggingBean]:15 - - ********** SmartLifecycle isAutoStartup
[some.packge.testapp.LifecycleLoggingBean]:21 - - ********** SmartLifecycle getPhase
[some.packge.testapp.LifecycleLoggingBean]:43 - - ********** Lifecycle isRunning false
[some.packge.testapp.LifecycleLoggingBean]:15 - - ********** SmartLifecycle isAutoStartup
[some.packge.testapp.LifecycleLoggingBean]:27 - - ********** Lifecycle start
[org.springframework.web.servlet.DispatcherServlet]:547 - - Completed initialization in 953 ms
[some.packge.testapp.LifecycleLoggingBean]:21 - - ********** SmartLifecycle getPhase
[some.packge.testapp.LifecycleLoggingBean]:43 - - ********** Lifecycle isRunning true
[some.packge.testapp.LifecycleLoggingBean]:32 - - ********** SmartLifecycle stop
[some.packge.testapp.LifecycleLoggingBean]:39 - - ********** Lifecycle stop
다음은 xml 구성이있는 로그입니다.
[org.springframework.web.context.ContextLoader]:271 - - Root WebApplicationContext: initialization started
[some.package.testapp.LifecycleLoggingBean]:15 - - ********** SmartLifecycle isAutoStartup
[some.package.testapp.LifecycleLoggingBean]:21 - - ********** SmartLifecycle getPhase
[some.package.testapp.LifecycleLoggingBean]:43 - - ********** Lifecycle isRunning false
[some.package.testapp.LifecycleLoggingBean]:15 - - ********** SmartLifecycle isAutoStartup
[some.package.testapp.LifecycleLoggingBean]:27 - - ********** Lifecycle start
[org.springframework.web.context.ContextLoader]:307 - - Root WebApplicationContext initialized in 1203 ms
[org.springframework.web.servlet.DispatcherServlet]:525 - - Initializing Servlet 'dispatcher'
[org.springframework.web.servlet.DispatcherServlet]:547 - - Completed initialization in 31 ms
[org.springframework.web.servlet.DispatcherServlet]:525 - - Initializing Servlet 'mvc'
[org.springframework.web.servlet.DispatcherServlet]:547 - - Completed initialization in 31 ms
다음은 LifecycleLoggingBean입니다.
@Component
public class LifecycleLoggingBean implements SmartLifecycle {
private final Logger logger = LoggerFactory.getLogger(LifecycleLoggingBean.class);
@Override
public boolean isAutoStartup() {
logger.info("********** SmartLifecycle isAutoStartup");
return true;
}
@Override
public int getPhase() {
// start last and stop first
logger.info("********** SmartLifecycle getPhase");
return Integer.MAX_VALUE;
}
private AtomicBoolean isRunning = new AtomicBoolean(false);
@Override
public void start() {
logger.info("********** Lifecycle start");
isRunning.set(true);
}
@Override
public void stop(Runnable callback) {
logger.info("********** SmartLifecycle stop");
stop();
callback.run();
}
@Override
public void stop() {
isRunning.set(false);
logger.info("********** Lifecycle stop");
}
public boolean isRunning() {
boolean rval = isRunning.get();
logger.info("********** Lifecycle isRunning {}", rval);
return rval;
}
}