【问题标题】:Spring Web Application: Post-DispatcherServlet initializationSpring Web 应用程序:Post-DispatcherServlet 初始化
【发布时间】:2013-06-16 05:23:44
【问题描述】:

我正在使用 Spring 3.2 DispatcherServlet。我正在寻找在DispatcherServlet 初始化完成后 发生的初始化挂钩;标准的 Spring 解决方案或 servlet 解决方案。有什么建议吗?

作为参考,servlet 启动后的最终记录语句如下。我希望我的初始化方法在 configured successfully log statement 之后立即执行。

DEBUG o.s.w.s.DispatcherServlet - Published WebApplicationContext of servlet 'mySpringDispatcherServlet' as ServletContext attribute with name [org.springframework.web.servlet.FrameworkServlet.CONTEXT.mySpringDispatcherServlet] 
INFO  o.s.w.s.DispatcherServlet - FrameworkServlet 'mySpringDispatcherServlet': initialization completed in 5000 ms   
DEBUG o.s.w.s.DispatcherServlet - Servlet 'mySpringDispatcherServlet' configured successfully 

根据我的研究,到目前为止,以下内容没有达到预期效果:

  1. 根据this answer 扩展ContextLoaderListener/实现ServletContextListener
  2. 根据the javaoc 实现WebApplicationInitializer
  3. 我的豆子使用@PostConstruct成功;我正在寻找一个 Servlet 或容器级别的钩子,它将在容器初始化和后处理 bean 之后执行。

【问题讨论】:

    标签: spring servlets spring-mvc initialization startup


    【解决方案1】:

    试试这个,改变你的端口号。 就我而言,我从 server.port=8001 更改为 server.port=8002

    【讨论】:

      【解决方案2】:

      您可以在应用程序上下文中实现ApplicationListener<ContextStartedEvent>。然后,将为您的 root context 调用此事件侦听器一次,并为每个 servlet context 调用一次。

      public class StartupListener implements ApplicationListener<ContextStartedEvent> {
      
          public void onApplicationEvent(ContextStartedEvent event) {
              ApplicationContext context = (ApplicationContext) event.getSource();
              System.out.println("Context '" + context.getDisplayName() + "' started.");
          }
      
      }
      

      如果您在 servlet 上下文 中定义此侦听器,则应该为 servlet 上下文本身调用一次。

      【讨论】:

      • 我在 web.xml 中注册了我的 StartupListener,但我得到了一个 RTE“原因:java.lang.ClassCircularityError: com/sun/beans/WeakCache”。
      • 我也找不到在我的&lt;servlet&gt; 声明中声明监听器的方法——&lt;listener&gt; 只能在&lt;web-app&gt; 下声明,对吧?如何使其特定于 servlet 上下文?
      • 您需要在 Spring servlet 上下文中声明它...如果您使用的是 XML 配置,则将其作为 &lt;bean&gt; 声明放在那里。这与基于标准的 JEE Servlet 侦听器无关。
      【解决方案3】:

      来自 Spring 的 Standard and Custom Events

      import org.springframework.context.ApplicationListener;
      import org.springframework.context.event.ContextRefreshedEvent;
      import org.springframework.stereotype.Component;
      
      @Component
      public class ApplicationContextListener implements
                                           ApplicationListener<ContextRefreshedEvent> {
      
          @Override
          public void onApplicationEvent(ContextRefreshedEvent event) {
              System.out.println("ApplicationContext was initialized or refreshed: "
                                     + event.getApplicationContext().getDisplayName());
          }
      
      }
      

      上面的事件会在 DispatcherServlet 初始化的时候触发,比如打印的时候:

      INFO  org.springframework.web.servlet.DispatcherServlet - FrameworkServlet 'ServletName': initialization completed in 1234 ms
      

      【讨论】:

        【解决方案4】:

        根本问题是我无法覆盖final 方法HttpsServlet.init()。我在DispatcherServlet.initWebApplicationContext 中找到了一个附近的@Override-able 方法,它确保我的bean 和上下文已完全初始化:

        @覆盖 受保护的 WebApplicationContext initWebApplicationContext() { WebApplicationContext wac = super.initWebApplicationContext(); // 通过以下方式对初始化的 Foo bean 进行处理: // wac.getBean(Foo.class); 返回结果; }

        【讨论】:

        • 不要那样做,因为那是一种非常糟糕的方式。正如在其他帖子中提到的那样,理想的位置是ApplicationListener&lt;ContextRefreshedEvent&gt;,它会在上下文完成加载后立即被触发。因此,无需在该类中创建自定义调度程序 servlet,只需添加一个侦听器即可。
        猜你喜欢
        • 1970-01-01
        • 2012-05-03
        • 2015-03-06
        • 2017-01-10
        • 1970-01-01
        • 2019-05-12
        • 2011-01-23
        • 2013-07-02
        • 1970-01-01
        相关资源
        最近更新 更多