67

我在 Web 应用程序中一起使用 jsf 和 spring。我已经在一个配置类中配置了数据源和会话工厂,它使用诸如此类的注释@Configuration, @ComponentScan我的项目中没有任何 applicationContext.xml 文件,因为我正在处理配置类中上下文 xml 的每个条目。测试用例成功运行,但是当我部署我的 Web 应用程序时,它给了我错误

java.lang.IllegalStateException:未找到 WebApplicationContext:未注册 ContextLoaderListener?

现在,如果我在 web.xml 中给出监听器类,

<listener>
        <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>

它给了我错误,

/WEB-INF/applicationContext.xml 未找到

根据 的文档ContextLoaderListener,确实如果我不明确给出contextConfigLocation参数web.xml,它会搜索名为applicationContext.xmlin的默认 spring 上下文文件web.xml。现在,如果我不想使用 spring 上下文文件并使用注释进行所有配置,我该怎么办?我应该如何注册监听器类ContextLoaderListener,以便在不使用 xml 文件和仅使用注释的情况下,我能够使用 spring 和 jsf 运行我的 Web 应用程序?

4

2 回答 2

132

web.xml你需要引导上下文AnnotationConfigWebApplicationContext

<servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <init-param>
        <param-name>contextClass</param-name>
        <param-value>
            org.springframework.web.context.support.AnnotationConfigWebApplicationContext
        </param-value>
    </init-param>
    <init-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
            org.package.YouConfigurationAnnotatedClass
        </param-value>
    </init-param>
</servlet>

并且不要忘记使用@EnableWebMvc您的 MVC 注释来启动。

进一步阅读:

编辑为“评论跟进”=>成为图灵完备:

是的,当然你需要一个听众。尽管上面完全回答了“如何在 web.xml 中注册 Spring @Configuration 注释类而不是 applicationContext.xml 文件”的问题,但这里有一个来自 Spring 官方文档的示例web.xml,该示例布局完整:

<web-app>
  <!-- Configure ContextLoaderListener to use AnnotationConfigWebApplicationContext
       instead of the default XmlWebApplicationContext -->
  <context-param>
      <param-name>contextClass</param-name>
      <param-value>
          org.springframework.web.context.support.AnnotationConfigWebApplicationContext
      </param-value>
  </context-param>

  <!-- Configuration locations must consist of one or more comma- or space-delimited
       fully-qualified @Configuration classes. Fully-qualified packages may also be
       specified for component-scanning -->
  <context-param>
      <param-name>contextConfigLocation</param-name>
      <param-value>com.acme.AppConfig</param-value>
  </context-param>

  <!-- Bootstrap the root application context as usual using ContextLoaderListener -->
  <listener>
      <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>

  <!-- Declare a Spring MVC DispatcherServlet as usual -->
  <servlet>
      <servlet-name>dispatcher</servlet-name>
      <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
      <!-- Configure DispatcherServlet to use AnnotationConfigWebApplicationContext
           instead of the default XmlWebApplicationContext -->
      <init-param>
          <param-name>contextClass</param-name>
          <param-value>
              org.springframework.web.context.support.AnnotationConfigWebApplicationContext
          </param-value>
      </init-param>
      <!-- Again, config locations must consist of one or more comma- or space-delimited
           and fully-qualified @Configuration classes -->
      <init-param>
          <param-name>contextConfigLocation</param-name>
          <param-value>com.acme.web.MvcConfig</param-value>
      </init-param>
  </servlet>

  <!-- map all requests for /app/* to the dispatcher servlet -->
  <servlet-mapping>
      <servlet-name>dispatcher</servlet-name>
      <url-pattern>/app/*</url-pattern>
  </servlet-mapping>
</web-app>
于 2011-11-10T07:11:00.207 回答
10

在这里提出一个老问题,但是使用最新版本的 Spring (v3.0+) 现在您可以完全摆脱 web.xml,前提是您将应用程序部署在支持 Servlet 3.0+ 的 Web 容器上。

可以实现 Spring 的WebApplicationInitializer接口来执行与 web.xml 中相同的配置。这个实现类将被运行在 Servlet 3.0+ 容器上的 Spring 3.0+ 应用程序自动检测到。

如果设置相当简单,您可以改用 Spring 提供的另一个类,如下所示。这里要做的就是设置@Configuration 类并列出servlet 映射。使设置非常简单。

public class WebInit extends AbstractAnnotationConfigDispatcherServletInitializer{

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return null;
    }

    @Override
    protected Class<?>[] getServletConfigClasses() {

        return new Class[] {AppConfig.class};
    }

    @Override
    protected String[] getServletMappings() {
        return new String[] {
                 "*.html"
                ,"*.json"
                ,"*.do"};
    }
}
于 2014-09-22T16:30:11.877 回答