如何设置Spring以便我可以省略applicationContext.xml

时间:2017-05-01 12:03:04

标签: java spring jersey jax-rs applicationcontext

我有一个使用spring来设置上下文的JAX应用程序。

我已经设置了一个AppConfig来处理这个...就像这样。

@Configuration
@ComponentScan("com.whatever")
public class AppConfig {... //etc

但是,我一直收到错误,因为应用程序正在寻找applicationContext.xml

org.springframework.beans.factory.BeanDefinitionStoreException: 
IOException parsing XML document from class path resource [applicationContext.xml];

我相信我必须对我的web.xml文件做些什么...但我无法弄明白。这是我的web.xml

<web-app version="3.1" xmlns="http://java.sun.com/xml/ns/javaee"
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
     xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_1.xsd">

<listener>
    <listener-class>com.whatever.etc.ApplicationListener</listener-class>
</listener>

<!-- Application -->
<servlet>
    <servlet-name>Jersey Web Application</servlet-name>
    <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
    <init-param>
        <param-name>jersey.config.server.provider.packages</param-name>
        <param-value>
            io.swagger.jaxrs.listing,
            com.shutterstock.media.api
        </param-value>
    </init-param>
    <init-param>
        <param-name>jersey.config.server.provider.scanning.recursive</param-name>
        <param-value>true</param-value>
    </init-param>
    <init-param>
        <param-name>javax.ws.rs.Application</param-name>
        <param-value>com.whatever.etc.MainClass</param-value>
    </init-param>
    <init-param>
        <param-name>dirAllowed</param-name>
        <param-value>false</param-value>
    </init-param>
    <init-param>
        <!-- used to overwrite default 4xx state pages -->
        <param-name>jersey.config.server.response.setStatusOverSendError</param-name>
        <param-value>true</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
    <async-supported>true</async-supported>
</servlet>

<servlet-mapping>
    <servlet-name>Jersey Web Application</servlet-name>
    <url-pattern>/*</url-pattern>
</servlet-mapping>

<!-- Swagger -->
<servlet>
    <servlet-name>Jersey Swagger</servlet-name>
    <servlet-class>io.swagger.jersey.config.JerseyJaxrsConfig</servlet-class>
    <load-on-startup>2</load-on-startup>
</servlet>

</web-app>

2 个答案:

答案 0 :(得分:1)

我能给你的最佳建议是将你的项目完全转换为弹簧启动,以便充分利用它提供的所有强大功能。

您应该从项目中完全删除所有XML并执行以下步骤:

<强> TL; DR

从spring boot启动的一个简单方法是使用spring initializr(Spring initializr)并开始将代码迁移到新项目。

解释在现有项目中迁移到spring boot的开始步骤:

Maven依赖

添加以下依赖项并删除所有其他相关的spring依赖项。一般情况下,如果您需要任何其他依赖项,请首先检查是否有弹簧启动启动器。 (同时确保您的包装为jar。如果您需要war,请访问此链接:convert to war

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>1.5.3.RELEASE</version>
    <relativePath/> <!-- lookup parent from repository -->
</parent>

<dependencies>
    <!-- Spring Boot -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-jersey</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-tomcat</artifactId>
        <scope>provided</scope>
    </dependency>
    <!-- Test -->
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>
</dependencies>

<build>
    <plugins>
        <plugin>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-maven-plugin</artifactId>
        </plugin>
    </plugins>
</build>

Spring Boot Application

创建一个使用@SpringBootApplication注释的类,在您的基础包中看起来如下所示。从这一点开始,仅在此包的子包中创建类,因此spring可以自动捕获所有组件:

@SpringBootApplication
public class FooApplication {

    public static void main(String[] args) {
        SpringApplication.run(FooApplication .class, args);
    }

}

Java配置

现在您可以轻松地在您的基础软件包下添加一个名为config的软件包,并使用您的自定义配置添加@Configuration带注释的bean。

<强> application.properites / YML

如果您还没有,请将application.properties/yml添加到src/main.resources,并至少配置以下配置(可在此处找到更多属性:spring boot common properties

  • 通过添加:spring.jersey.application-path=/
  • 映射泽西servlet端点

泽西岛配置

您需要在扩展ResourceConfig的自定义Java配置类中注册jersey提供程序:

@Configuration
public class JerseyConfiguration extends ResourceConfig {

    public JerseyConfiguration() {
        register(FooController.class);
        register(OtherController.class);
        ...
    }

}

重要提示

执行此转换后,您不再需要web.xml,因为spring boot负责为您创建servlet。您应该从项目中删除除pom.xml之外的所有XML并将所有XML转换为java。它可以使用@ImportResource与您的XML配置共存,但不建议这样做。

现在使用maven使用maven build运行项目时使用以下命令:spring-boot:run

如果您有系统提供的任何静态文件,请将其从src/main/webapp移至src/main/resources/static(此处提供更多信息:Static Content

所有这一切都应该让你开始使用spring boot并允许你删除applicationContext.xml,同时保持spring boot的最佳实践。你可以用一种更简单的方式做到这一点,但我认为从长远来看它会更好地为你服务。

答案 1 :(得分:1)

您收到错误是因为Jersey与Spring集成的默认方式是查找此applicationContext.xml文件。如果你想减少xml,你需要使用WebApplicationInitializer

以编程方式配置Spring
@Order(1)
public class SpringWebContainerInitializer implements WebApplicationInitializer {

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        registerContextLoaderListener(servletContext);

        // Set the Jersey used property so it won't load a ContextLoaderListener
        // see bug report https://java.net/jira/browse/JERSEY-2038
        servletContext.setInitParameter("contextConfigLocation", "");
    }

    private void registerContextLoaderListener(ServletContext servletContext) {
        WebApplicationContext webContext;
        webContext = createWebAplicationContext(SpringAnnotationConfig.class);
        servletContext.addListener(new ContextLoaderListener(webContext));
    }

    public WebApplicationContext createWebAplicationContext(Class... configClasses) {
        AnnotationConfigWebApplicationContext context;
        context = new AnnotationConfigWebApplicationContext();
        context.register(configClasses);
        return context;
    }
}

在此示例中,您可以看到

createWebAplicationContext(SpringAnnotationConfig.class)

只需在那里使用AppConfig

我们在这里做的是自己加载Spring上下文,当Jersey查找它时,它会找到它,而不是尝试加载上下文本身(否则它会尝试查找applicationContext.xml)文件)。

另见: