If Configuration class implements both ServletContextAware and DestructionAwareBeanPostProcessor then setServletContext will not be called.
Steps to reproduce:
- Init a project https://start.spring.io/
- Maven project, Spring boot 2.4.1, Java 8
- Add
spring-boot-starter-web dependency
- Add two configuration classes
DemoConfig
package com.example.demo;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.DestructionAwareBeanPostProcessor;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ServletContextAware;
@Configuration
public class DemoConfig implements DestructionAwareBeanPostProcessor, ServletContextAware {
private static final Logger LOG = LoggerFactory.getLogger( DemoConfig.class );
private ServletContext servletContext;
@PostConstruct
public void init() {
LOG.warn( "init() {}", servletContext );
}
@Override
public void postProcessBeforeDestruction( Object bean, String beanName ) throws BeansException {
}
@Override
public void setServletContext( ServletContext servletContext ) {
LOG.warn( "setServletContext() {}", servletContext );
this.servletContext = servletContext;
}
}
AnotherConfig
package com.example.demo;
import javax.annotation.PostConstruct;
import javax.servlet.ServletContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.ServletContextAware;
@Configuration
public class AnotherConfig implements ServletContextAware {
private static final Logger LOG = LoggerFactory.getLogger( AnotherConfig.class );
private ServletContext servletContext;
@PostConstruct
public void init() {
LOG.warn( "init() {}", servletContext );
}
@Override
public void setServletContext( ServletContext servletContext ) {
LOG.warn( "setServletContext() {}", servletContext );
this.servletContext = servletContext;
}
}
Logs:
2020-12-18 22:17:01.742 INFO 331634 --- [ main] com.example.demo.DemoApplication : Starting DemoApplication using Java 1.8.0_265 on zaynetro-thinkpad with PID 331634 (/home/zaynetro/Code/trial/demo-spring-boot/target/classes started by zaynetro in /home/zaynetro/Code/trial/demo-spring-boot)
2020-12-18 22:17:01.745 DEBUG 331634 --- [ main] com.example.demo.DemoApplication : Running with Spring Boot v2.4.1, Spring v5.3.2
2020-12-18 22:17:01.746 INFO 331634 --- [ main] com.example.demo.DemoApplication : No active profile set, falling back to default profiles: default
2020-12-18 22:17:02.367 WARN 331634 --- [ main] com.example.demo.DemoConfig : init() null
2020-12-18 22:17:02.614 INFO 331634 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2020-12-18 22:17:02.623 INFO 331634 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-12-18 22:17:02.623 INFO 331634 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.41]
2020-12-18 22:17:02.668 INFO 331634 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-12-18 22:17:02.668 INFO 331634 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 873 ms
2020-12-18 22:17:02.713 WARN 331634 --- [ main] com.example.demo.AnotherConfig : setServletContext() org.apache.catalina.core.ApplicationContextFacade@299266e2
2020-12-18 22:17:02.713 WARN 331634 --- [ main] com.example.demo.AnotherConfig : init() org.apache.catalina.core.ApplicationContextFacade@299266e2
2020-12-18 22:17:02.842 INFO 331634 --- [ main] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2020-12-18 22:17:02.985 INFO 331634 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
setServletContext is called correctly for AnotherConfig but never called for DemoConfig.
If Configuration class implements both
ServletContextAwareandDestructionAwareBeanPostProcessorthensetServletContextwill not be called.Steps to reproduce:
spring-boot-starter-webdependencyDemoConfig
AnotherConfig
Logs:
setServletContextis called correctly forAnotherConfigbut never called forDemoConfig.