【发布时间】:2015-03-13 08:47:03
【问题描述】:
我正在使用 spring-mvc 框架开发一个简单的 Web 应用程序。
我的配置只有一个 mvc-dispatcher Servlet,(org.springframework.web.servlet.DispatcherServlet),我所有的配置都在META-INF\mvc-dispatcher-servlet.xml;我没有application.xml。
特别是 mvc-dispatcher-servlet.xml 自动装配我所有的 bean。
我想在我的 Web 应用程序启动时执行一段代码,而这段代码需要一些我需要注入的 bean。
我发现的所有示例都建议实施 WebApplicationInitializer 或 ServletContextListener。但对我来说问题是这两个接口都允许在我的主要唯一 Servlet 启动之前执行我的代码,因此在此之前我的 bean 是自动连接的。
@WebListener
public class MyCustomListener implements ServletContextListener {
@Autowired
private MyBean myBean;
@Override
public void contextInitialized(ServletContextEvent sce) {
// I have tried the following to inject the beans:
SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(sce.getServletContext());
WebApplicationContextUtils
.getRequiredWebApplicationContext(sce.getServletContext())
.getAutowireCapableBeanFactory()
.autowireBean(this);
WebApplicationContextUtils
.getWebApplicationContext(sce.getServletContext())
.getAutowireCapableBeanFactory()
.autowireBean(this);
myBean.doStuff(); //NullPointerException
}
@Override
public void contextDestroyed(ServletContextEvent servletContextEvent) {
}
}
我尝试使用WebApplicationContextUtils 或SpringBeanAutowiringSupport 之类的方式将我的依赖项注入到监听器中,但我的webapplication 上下文始终为空;如果我没记错的话,那是因为spring的FrameworkServlet还没有读取mvc-dispatcher-servlet.xml并创建了webApplicationContext:
来自FrameworkServlet.initServletBean:
// this code that create the WebapplicationContext
// is executed after my custom listener
this.webApplicationContext = initWebApplicationContext();
在我的情况下,执行需要 bean 的代码的标准方法是什么(即只有一个 DispatcherServlet 来处理所有配置)?
编辑:
我的 web.xml 非常标准:
<web-app ... >
<display-name>Spring MVC Application</display-name>
<servlet>
<servlet-name>mvc-dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<load-on-startup>0</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>mvc-dispatcher</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
我尝试实现ApplicationListener<ContextRefreshedEvent>,但是当我启动我的服务器时,ContextRefreshedEvent 从未被触发:
@WebListener
public class MyCustomListener implements ApplicationListener<ContextRefreshedEvent> {
@Autowired
private MyBean myBean;
// I don't know why this event is never fired?
@Override
public void onApplicationEvent(ContextRefreshedEvent event) {
myBean.doStuff();
}
}
我应该在web.xml 和/或mvc-dispatcher-servlet.xml 中添加一个参数来触发事件吗?
【问题讨论】:
-
你能发布你的 web.xml 吗?
-
A
ServletContextListener永远不会工作,因为您只有一个DispatcherServlet在调用该组件时还没有准备好。创建一个实现ApplicationListener<ContextRefreshedEvent>的bean,该事件将在上下文已加载并准备就绪时触发。在你需要实现的方法中,你可以为所欲为。 -
Nicolas,你是如何在
@WebListener中使用@Autowired的?
标签: spring spring-mvc servlets dependency-injection javabeans