【问题标题】:Spring - Startup code with dependency injectionSpring - 具有依赖注入的启动代码
【发布时间】: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。

我发现的所有示例都建议实施 WebApplicationInitializerServletContextListener。但对我来说问题是这两个接口都允许在我的主要唯一 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) {
    }
}

我尝试使用WebApplicationContextUtilsSpringBeanAutowiringSupport 之类的方式将我的依赖项注入到监听器中,但我的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&lt;ContextRefreshedEvent&gt;,但是当我启动我的服务器时,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&lt;ContextRefreshedEvent&gt; 的bean,该事件将在上下文已加载并准备就绪时触发。在你需要实现的方法中,你可以为所欲为。
  • Nicolas,你是如何在 @WebListener 中使用 @Autowired 的?

标签: spring spring-mvc servlets dependency-injection javabeans


【解决方案1】:

看来你需要在 Spring 上下文初始化后执行一些代码。而不是在它之前。您可以使用ApplicationListenerContextRefreshedEvent 事件。

公共类 CustomInitializerClass 实现 应用监听器{

public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent ) {

} }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-02
    • 2018-11-21
    相关资源
    最近更新 更多