WebApplicationContextUtils.getWebApplicationContext(ServletContext) returns 来自 ServletContextListener 的 NULL
WebApplicationContextUtils.getWebApplicationContext(ServletContext) returns NULL from ServletContextListener
我无法在 ServletContextListener 中获取 WebApplicationContext。我搜索了解决方案,但没有一个对我有用。如果有人能提供帮助,我将不胜感激。提前致谢。
以下是代码片段-
我的 AppConfig class:
package in.andonsystem.config;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"in.andonsystem"})
public class AppConfig extends WebMvcConfigurerAdapter{
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public MessageSource messageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
我的 AppInitializer Class.
package in.andonsystem.config;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class Appinitializer implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
rootContext.setServletContext(servletContext);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
rootContext.refresh();
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
我的 ContextListener Class:
package in.andonsystem.config;
import com.mysql.jdbc.AbandonedConnectionCleanupThread;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
@WebListener
public class ContextListener implements ServletContextListener{
private Logger logger = Logger.getLogger("ContextListener");
@Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("contextInitialized()");
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
System.out.println("Is rootContext null:" + (rootContext == null));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
stdout 输出总是成真。
我错过了什么?
终于想出办法了。问题是 ServletContextListener 在 ContextLoaderListener 之前加载,因此返回的 WebApplicationContext 为空,因为 ContextLoaderListener 必须在 ServletContextListener 之前加载才能获得 rootContext。
我从我的 ContextListener 中删除了 @WebListener 注释,并在添加 ContextLoaderListener 后以编程方式在 AppInitializer 的 onStartup 方法中添加了这个监听器。
现在我没有 @WebListener 注释的 ContextListener 是:
public class ContextListener implements ServletContextListener{
private Logger logger = Logger.getLogger("ContextListener");
@Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("contextInitialized()");
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
System.out.println("Is rootContext null:" + (rootContext == null));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
logger.info("contextDestroyed()");
}
}
AppInitializer 是:
public class Appinitializer implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
rootContext.setServletContext(servletContext);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
//ContextListener must be added after ContextLoaderListener
servletContext.addListener(ContextListener.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
看起来基本正确,但我认为您应该从初始化程序中删除以下两行 class:
rootContext.setServletContext(servletContext);
和
rootContext.refresh();
我无法在 ServletContextListener 中获取 WebApplicationContext。我搜索了解决方案,但没有一个对我有用。如果有人能提供帮助,我将不胜感激。提前致谢。
以下是代码片段- 我的 AppConfig class:
package in.andonsystem.config;
import org.springframework.context.MessageSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ResourceBundleMessageSource;
import org.springframework.web.servlet.ViewResolver;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.InternalResourceViewResolver;
import org.springframework.web.servlet.view.JstlView;
@Configuration
@EnableWebMvc
@ComponentScan(basePackages = {"in.andonsystem"})
public class AppConfig extends WebMvcConfigurerAdapter{
@Bean
public ViewResolver viewResolver(){
InternalResourceViewResolver viewResolver = new InternalResourceViewResolver();
viewResolver.setViewClass(JstlView.class);
viewResolver.setPrefix("WEB-INF/views/");
viewResolver.setSuffix(".jsp");
return viewResolver;
}
@Bean
public MessageSource messageSource(){
ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource();
messageSource.setBasename("messages");
return messageSource;
}
@Override
public void addResourceHandlers(ResourceHandlerRegistry registry) {
registry.addResourceHandler("/static/**").addResourceLocations("/static/");
}
}
我的 AppInitializer Class.
package in.andonsystem.config;
import javax.servlet.ServletRegistration;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.ContextLoaderListener;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;
public class Appinitializer implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
rootContext.setServletContext(servletContext);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
rootContext.refresh();
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
我的 ContextListener Class:
package in.andonsystem.config;
import com.mysql.jdbc.AbandonedConnectionCleanupThread;
import java.sql.Driver;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Enumeration;
import java.util.logging.Logger;
import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import javax.servlet.annotation.WebListener;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.support.WebApplicationContextUtils;
@WebListener
public class ContextListener implements ServletContextListener{
private Logger logger = Logger.getLogger("ContextListener");
@Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("contextInitialized()");
WebApplicationContext rootContext = WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
System.out.println("Is rootContext null:" + (rootContext == null));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
}
stdout 输出总是成真。 我错过了什么?
终于想出办法了。问题是 ServletContextListener 在 ContextLoaderListener 之前加载,因此返回的 WebApplicationContext 为空,因为 ContextLoaderListener 必须在 ServletContextListener 之前加载才能获得 rootContext。
我从我的 ContextListener 中删除了 @WebListener 注释,并在添加 ContextLoaderListener 后以编程方式在 AppInitializer 的 onStartup 方法中添加了这个监听器。
现在我没有 @WebListener 注释的 ContextListener 是:
public class ContextListener implements ServletContextListener{
private Logger logger = Logger.getLogger("ContextListener");
@Override
public void contextInitialized(ServletContextEvent sce) {
logger.info("contextInitialized()");
WebApplicationContext rootContext =
WebApplicationContextUtils.getWebApplicationContext(sce.getServletContext());
System.out.println("Is rootContext null:" + (rootContext == null));
}
@Override
public void contextDestroyed(ServletContextEvent sce) {
logger.info("contextDestroyed()");
}
}
AppInitializer 是:
public class Appinitializer implements WebApplicationInitializer{
@Override
public void onStartup(ServletContext servletContext) throws ServletException {
AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext();
rootContext.register(AppConfig.class);
rootContext.setServletContext(servletContext);
// Manage the lifecycle of the root application context
servletContext.addListener(new ContextLoaderListener(rootContext));
//ContextListener must be added after ContextLoaderListener
servletContext.addListener(ContextListener.class);
// Register and map the dispatcher servlet
ServletRegistration.Dynamic dispatcher =
servletContext.addServlet("dispatcher", new DispatcherServlet(rootContext));
dispatcher.setLoadOnStartup(1);
dispatcher.addMapping("/");
}
}
看起来基本正确,但我认为您应该从初始化程序中删除以下两行 class:
rootContext.setServletContext(servletContext);
和
rootContext.refresh();