1.概述
这是关于使用Spring 3.1和基于Java的配置来建立RESTfull Web应用程序的系列教程的第一篇。 本文将重点介绍如何引导Web应用程序 ,讨论如何从XML过渡到Java,而不必完全迁移整个XML配置。
2. Maven
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="
http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org</groupId>
<artifactId>rest</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>war</packaging>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${spring.version}</version>
<exclusions>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cglib</groupId>
<artifactId>cglib-nodep</artifactId>
<version>${cglib.version}</version>
<scope>runtime</scope>
</dependency>
</dependencies>
<build>
<finalName>rest</finalName>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.6</source>
<target>1.6</target>
<encoding>UTF-8</encoding>
</configuration>
</plugin>
</plugins>
</build>
<properties>
<spring.version>3.2.2.RELEASE</spring.version>
<cglib.version>2.2.2</cglib.version>
</properties>
</project>
2.1。 cglib依赖关系的证明
您可能想知道为什么cglib是一个依赖项-事实证明有理由将其包含在其中-没有它,整个配置将无法运行。 如果删除,Spring将抛出:
原因:java.lang.IllegalStateException:处理@Configuration类需要CGLIB。 将CGLIB添加到类路径或删除以下@Configuration bean定义
Spring处理@Configuration类的方式解释了发生这种情况的原因。 这些类实际上是bean,因此,它们需要了解Context,并尊重范围和其他bean语义。 这是通过针对每个@Configuration类动态创建具有此意识的cglib代理来实现的,因此可以实现cglib依赖性。
此外,因此,对配置注释类有一些限制:
- 配置类不应是最终的
- 他们应该有一个没有参数的构造函数
2.2。 Spring 3.2中的cglib依赖项
从Spring 3.2开始, 不再需要将cglib添加为显式依赖项 。 这是因为Spring现在正在内联cglib –这将确保所有基于类的代理功能都可以在Spring 3.2中立即使用。
新的cglib代码位于Spring包下: org.springframework.cglib (替换原始的net.sf.cglib )。 更改软件包的原因是为了避免与类路径上已经存在的任何cglib版本冲突。
另外,现在使用新的cglib 3.0,它是从较早的2.2依赖项升级的(有关更多详细信息,请参见JIRA问题 )。
3.基于Java的Web配置
@Configuration
@ImportResource( { "classpath*:/rest_config.xml" } )
@ComponentScan( basePackages = "org.rest" )
@PropertySource({ "classpath:rest.properties", "classpath:web.properties" })
public class AppConfig{
@Bean
public static PropertySourcesPlaceholderConfigurer properties() {
return new PropertySourcesPlaceholderConfigurer();
}
}
首先, @Configuration批注–这是基于Java的Spring配置使用的主要工件。 它本身使用@Component进行元注释,这使注释的类成为标准bean ,因此也成为组件扫描的候选对象。 @Configuration类的主要目的是成为Spring IoC容器的bean定义的来源。 有关更详细的描述,请参见官方文档 。
然后, @ ImportResource用于导入基于XML的现有Spring配置。 这可能是仍在从XML迁移到Java的配置,或者只是您希望保留的传统配置。 无论哪种方式,将其导入到容器对于成功迁移都是必不可少的,它允许很小的步骤而没有太大的风险。 替换的等效XML注释是:
<import resource =” classpath *:/ rest_config.xml” />
继续@ComponentScan –这将配置组件扫描指令,有效地替换XML:
<context:component-scan base-package="org.rest" />
从Spring 3.1开始,默认情况下, @ Configuration不包括在类路径扫描中,请参见JIRA问题 。 在Spring 3.1之前,这些类应明确排除在外:
excludeFilters = { @ComponentScan.Filter( Configuration.class ) }
@Configuration类不应被自动发现,因为它们已由Container指定并使用-允许重新发现它们并将其引入Spring上下文将导致以下错误:
由以下原因引起:org.springframework.context.annotation.ConflictingBeanDefinitionException:豆类[org.rest.spring.AppConfig]的由注释指定的豆名称'webConfig'与同名和类[org.net]的现有,不兼容的豆定义冲突。 rest.spring.AppConfig]
最后,使用@Bean批注配置属性支持 – PropertySourcesPlaceholderConfigurer在@Bean批注的方法中初始化,指示它将产生由Container管理的Spring bean。 此新配置已替换以下XML:
<context:property-placeholder
location="classpath:persistence.properties, classpath:web.properties"
ignore-unresolvable="true"/>
有关为什么需要手动注册PropertySourcesPlaceholderConfigurer bean的详细讨论,请参见带有Spring教程的属性 。
3.1。 web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns="
http://java.sun.com/xml/ns/javaee"
xmlns:web="http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
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_0.xsd"
id="rest" version="3.0">
<context-param>
<param-name>contextClass</param-name>
<param-value>
org.springframework.web.context.support.AnnotationConfigWebApplicationContext
</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>org.rest.spring.root</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>rest</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.rest.spring.rest</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>rest</servlet-name>
<url-pattern>/api/*</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file />
</welcome-file-list>
</web-app>
首先,定义根上下文并将其配置为使用AnnotationConfigWebApplicationContext而不是默认的XmlWebApplicationContext 。 较新的AnnotationConfigWebApplicationContext接受带注解的@Configuration的类作为Container配置的输入,这是设置基于Java的上下文所必需的。
与XmlWebApplicationContext不同,它不假定默认配置类位置,因此必须设置Servlet的“ contextConfigLocation” init-param 。 这将指向@Configuration类所在的java包。 还支持类的完全限定名称。
接下来,将DispatcherServlet配置为使用相同类型的上下文,唯一的区别是它从不同的包中加载配置类。
除此之外, web.xml并没有真正从XML更改为基于Java的配置。
4。结论
提出的方法允许将Spring配置从XML平滑迁移到Java,同时将新旧混合在一起。 这对于较旧的项目很重要,因为较旧的项目可能具有许多基于XML的配置,无法一次全部迁移。 这样,应用程序的web.xml和引导程序是迁移的第一步,之后可以以较小的增量移植其余的XML bean。
在关于REST with Spring的下一篇文章中 ,我将介绍如何在项目中设置MVC,HTTP状态代码的配置,有效负载编组和内容协商。 同时,您可以签出github项目 。
翻译自: https://www.javacodegeeks.com/2011/11/bootstrapping-web-application-with.html