【问题标题】:Make ServletContextListener spring aware使 ServletContextListener 具有弹簧意识
【发布时间】:2017-02-16 11:22:07
【问题描述】:

我正在将 Spring 插入现有的 Java EE Web 应用程序。我的 web.xml 中有以下几行:

<listener>
    <listener-class>com.MyContextListener</listener-class>
</listener> 

并关注MyContextListener 类?

public class MyContextListener implements ServletContextListener {

    public void contextInitialized(ServletContextEvent event) {
       //...
    }
}

我应该怎么做才能让MyContextListener被Spring管理?


已编辑:

我的假设是:Spring 应该创建所有 servlet 和所有 Web 应用程序基础架构,因此在 MyContextListenercontextInitialized 方法中发生的所有事情都应该由 Spring 以某种方式处理。我怎么能通过实现我想的一些接口来实现。如果我错了,请纠正我。谢谢!

【问题讨论】:

  • 你想把 Spring bean 注入这个监听器吗?
  • 为什么需要 Spring 来感知这个监听器?您能否添加更多关于您需要实现的目标的信息?
  • 这是您要找的吗? stackoverflow.com/questions/8686507/… 添加ApplicationListener 接口并注册一个bean 将让您处理spring 生命周期。如果你能提供更多关于你想要达到的目标的信息,那就太好了。告诉我
  • @MaciejWalkowiak,我们可以不将 Spring bean 注入那个监听器吗?
  • 仅以 hacky 方式。我不推荐,但如果你必须看:stackoverflow.com/questions/4746041/…

标签: java spring spring-mvc


【解决方案1】:

如果在 Spring Boot 中使用 Java 配置,请使用 @Bean 注释创建 MyContextListener 的新实例。

【讨论】:

    【解决方案2】:

    使用 @WebListener 注释类或使用 @Bean

    注释方法

    【讨论】:

      【解决方案3】:

      我应该怎么做才能让MyContextListener被Spring管理?

      这取决于您使用的配置方式。无论如何,你应该直接告诉 Spring 使用你声明的类。这可以通过以下方式完成:

      @WebListener
      public class MyContextListener implements ServletContextListener { ... }
      

      标有此注解 (the Servlet 3.0 specification, 8.1.4) 的类必须实现这些接口之一

      HttpSessionAttributeListener
      HttpSessionListener
      ServletContextAttributeListener
      ServletContextListener (+)
      ServletRequestAttributeListener
      ServletRequestListener
      HttpSessionIdListener
      

      确实如此。

      就个人而言,我更喜欢基于元注释的方法,这使我的配置更短更简洁。

      Spring 应该创建所有 servlet 和所有 Web 应用程序基础架构,因此在 MyContextListenercontextInitialized 方法中发生的所有事情都应该由 Spring 以某种方式处理。

      是的,如果您提供一些可以帮助它注册/配置/创建/管理实例的信息,Spring 会为您完成。

      信息可能是元信息(一个告诉如何创建实例的模板,例如BeanDefinitions)或已完成的实例本身(通常,它以编程方式传递,进而导致编写大量代码)。

      我怎样才能实现,通过实现一些我想的接口。

      您正在实现一个接口,以使您的侦听器成为侦听器(描述特定方法的类,这些方法将在某些时间点调用)。 Spring 本身负责保证 此类调用这些时间点,之前将对象放置在现有的 Web 基础架构中。

      【讨论】:

      • 如果您使用@Component 而不是@WebListener,那么您可以像往常一样在本课程中使用@Autowire
      【解决方案4】:

      嗯,

      我们有一个类似的场景,将现有的 Jersey Web 服务应用程序配置为使用 Spring 进行依赖注入。我们的 Jersey webapp 扩展了 ContextLoaderListener 如下

      public class XServletContextListener extends ContextLoaderListener {
          ... 
          @Override
          public void contextInitialized(ServletContextEvent arg0) {
              super.contextInitialized(arg0);
              ....
          }
      
          @Override
          public void contextDestroyed(ServletContextEvent arg0) {
              super.contextDestroyed(arg0);
              ....
          }
      } 
      

      其中 ContextLoaderListener

      import org.springframework.web.context.ContextLoaderListener;
      

      我们包含了 jersey-spring 桥和所有 spring 依赖项,包括 applicationContext.xml 如下

      <beans xmlns="http://www.springframework.org/schema/beans"
          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
          xmlns:context="http://www.springframework.org/schema/context"
          xsi:schemaLocation="http://www.springframework.org/schema/beans
          http://www.springframework.org/schema/beans/spring-beans-4.0.xsd
          http://www.springframework.org/schema/context
          http://www.springframework.org/schema/context/spring-context-4.0.xsd">
      
          <context:component-scan base-package="com.xxx.*" />
          ....
          ....
      </beans>
      

      显然需要确保 XServletContextListener 包含在 web.xml 中,如下所示

      <context-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>/WEB-INF/applicationContext.xml</param-value>
      </context-param>
      <listener>
          <listener-class>com.xxx.**.XServletContextListener</listener-class>
      </listener>
      

      之后是 servlet 及其 init-param 值和 servlet 映射。您显然可以采用注释配置代替 xml confib,在这种情况下,您需要使用 WebListener 注释。

      我们使用各种注解如

      @Component for objects
      @Service for services 
      @Repository for DAOs
      @Controller for controllers/resources 
      @ContextConfiguration for tests
      

      一切都由 Spring 框架加载和自动装配

      【讨论】:

      • 为什么选择jersey? OP没有提到它
      • Jersey 只是一个 Web 层,仅此而已(根据需要将其替换为 spring-mvc,它不会影响所提出的问题)。无论如何,这是我为我的一个使用 jersey 的项目开发的解决方案,因为我发现该解决方案与所提出的问题密切相关,因此我在这里分享了它。就像我说的,提到球衣没有区别
      • 应用的原始监听器呢?你把它们转换成 Spring bean 了吗?
      猜你喜欢
      • 2011-06-29
      • 2010-11-26
      • 2011-09-19
      • 1970-01-01
      • 1970-01-01
      • 2013-09-09
      • 1970-01-01
      • 2017-03-23
      • 2017-12-22
      相关资源
      最近更新 更多