简体   繁体   English

Spring-具有依赖项注入的启动代码

[英]Spring - Startup code with dependency injection

I'm working on a simple web application using spring-mvc framework. 我正在使用spring-mvc框架开发一个简单的Web应用程序。

My configuration only has one single mvc-dispatcher Servlet, ( org.springframework.web.servlet.DispatcherServlet ), and all my configuration is in the META-INF\\mvc-dispatcher-servlet.xml ; 我的配置只有一个mvc-dispatcher Servlet( org.springframework.web.servlet.DispatcherServlet ),而我的所有配置都在META-INF\\mvc-dispatcher-servlet.xml I don't have any application.xml . 我没有任何application.xml

Especially, the mvc-dispatcher-servlet.xml autowire all my beans. 特别是, mvc-dispatcher-servlet.xml自动连接我的所有bean。

I would like to execute a piece of code at the startup of my web application, and this code need some beans that I need to inject. 我想在Web应用程序启动时执行一段代码,并且此代码需要一些需要注入的bean。

All the examples that I've found advice to implement WebApplicationInitializer or ServletContextListener . 我发现的所有示例都建议实现WebApplicationInitializerServletContextListener But the problem for me is that both these interface allow to execute my code before the start-up of my main unique Servlet, and therefore, before that my beans are auto-wired. 但是对我来说,问题是这两个接口都允许在我的主要唯一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) {
    }
}

I've tried to inject my dependencies into the Listener, using something like WebApplicationContextUtils or SpringBeanAutowiringSupport , but my webapplication context is always null; 我曾尝试使用WebApplicationContextUtilsSpringBeanAutowiringSupport类的东西将依赖项注入到Listener中,但是我的Web应用程序上下文始终为null。 if I'm not mistaken, it's because the FrameworkServlet of spring hasn't read the mvc-dispatcher-servlet.xml and created the webApplicationContext yet: 如果我没记错的话,那是因为spring的FrameworkServlet尚未读取mvc-dispatcher-servlet.xml并创建了webApplicationContext:

From FrameworkServlet.initServletBean : FrameworkServlet.initServletBean

// this code that create the WebapplicationContext
// is executed after my custom listener
this.webApplicationContext = initWebApplicationContext();

What is the standard way to execute code that require beans in my case (ie with only a single DispatcherServlet that handle all the configuration)? 在我的情况下,执行需要Bean的代码的标准方法是什么(即仅使用一个处理所有配置的DispatcherServlet)?

Edit: 编辑:

My web.xml is pretty standard: 我的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>

I tried to implement the ApplicationListener<ContextRefreshedEvent> , but the ContextRefreshedEvent is never fired when I start my server: 我尝试实现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();
    }
}

Is there a parameter that I should add in my web.xml and/or mvc-dispatcher-servlet.xml to trigger the event ? 我应该在我的web.xml和/或mvc-dispatcher-servlet.xml添加一个参数来触发事件吗?

It seems you need to execute some code after Spring context is initialized. 似乎您需要在Spring上下文初始化之后执行一些代码。 and not before it. 而不是之前。 You could use ContextRefreshedEvent event of the ApplicationListener . 您可以使用ApplicationListener ContextRefreshedEvent事件。

public class CustomInitializerClass implements ApplicationListener{ 公共类CustomInitializerClass实现ApplicationListener {

 public void onApplicationEvent(ContextRefreshedEvent contextRefreshedEvent ) { } } 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM