简介
从诞生之初,Spring框架就坚守它的宗旨:简化企业级应用开发,同时给复杂问题提供强大的、非侵入性解决方案。一年前发布的Spring2.0就把这些主题推到了一个新的高度。XML Schema的支持和自定义命名空间的使用大大减少了基于XML的配置。使用Java5及更新版本java的开发人员如今可以利用植入了像泛型(generic)和注解等新语言特性的Spring库。最近,和AspectJ表达式语言的紧密集成,使得以非侵入方式添加跨越定义良好的Spring管理对象分组的行为成为可能。
新发布的Spring2.5继续坚持了这个发展趋向,特别是为那些使用Java 5或更新版本java的开发人员提供了进一步简化而强大的新特性。这些新特性包括:注解驱动的依赖性注入(annotation-driven dependency injection),使用注解而非XML元数据来自动侦测classpath上的Spring组件,注解对生命周期方法的支持,一个新的web控制器模型将请求映射到加注解的方法上,在测试框架中支持Junit4,Spring XML命名空间的新增内容,等等。
本文是探讨这些新特性的3篇系列文章中的第一篇。本文将主要关注于简化的配置和在Spring应用程序上下文(application context)核心新增的基于注解的功能;第二篇文章将涵盖web层可用的新特性;最后一篇文章将着重介绍集成和测试的新增性能。这一系列的三篇文章中引用的例子都基于Spring PetClinic应用程序范例。此范例最近被重构以用于展示Spring最新功能,并被包含于Spring 2.5的发布下载包中,可以从Spring Framework 下载网页下载。查看"samples/petclinic"目录下的"readme.txt"文件可以得知关于如何构建和部署PetClinic应用程序,掌握本文提到的新技术的最佳方法也许就是对PetClinic应用程序中所展示的特性进行试验。
Spring支持JSR-250注解
Java EE5中引入了“Java平台的公共注解(Common Annotations for the Java Platform)”,而且该公共注解从Java SE 6一开始就被包含其中。 2006年5月,BEA系统宣布了他们在一个名为Pitchfork的项目上与Interface21的合作,该项目提供了基于Spring的Java EE 5编程模型的实现,包括支持用于注入(injection)、拦截( interception)和事务处理(transactions)的JSR-250注解和EJB 3注解(JSR-220)。 在2.5版本中,Spring框架的核心(core)现在支持以下JSR-250注解:
- @Resource
- @PostConstruct
- @PreDestroy
结合Spring,这些注解在任何开发环境下都可以使用——无论是否有应用程序服务器——甚至是集成测试环境都可以。激活这样的支持仅仅是注册一个单独的Spring post-processor的事情:
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"/>
@Resource注解
@Resource 注解被用来激活一个命名资源(named resource)的依赖注入,在JavaEE应用程序中,该注解被典型地转换为绑定于JNDI context中的一个对象。 Spring确实支持使用@Resource通过JNDI lookup来解析对象,默认地,拥有与@Resource注解所提供名字相匹配的“bean name(bean名字)”的Spring管理对象会被注入。 在下面的例子中,Spring会向加了注解的setter方法传递bean名为“dataSource”的Spring管理对象的引用。
@Resource(name="dataSource")
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
直接使用@Resource注解一个域(field)同样是可能的。通过不暴露setter方法,代码愈发紧凑并且还提供了域不可修改的额外益处。正如下面将要证明的,@Resource注解甚至不需要一个显式的字符串值,在没有提供任何值的情况下,域名将被当作默认值。
@Resource
private DataSource dataSource; // inject the bean named 'dataSource'
该方式被应用到setter方法的时候,默认名是从相应的属性衍生出来,换句话说,命名为'setDataSource'的方法被用来处理名为'dataSource'的属性。
private DataSource dataSource;
@Resource
public void setDataSource(DataSource dataSource) {
this.dataSource = dataSource;
}
当@Resource没有显式提供名字的时候,如果根据默认名字找不到对应的Spring管理对象,注入机制会回滚至类型匹配(type-match)。如果刚好只有一个Spring管理对象符合该依赖的类型,那么它会被注入。通过设置CommonAnnotationBeanPostProcessor 的‘fallbackToDefaultTypeMatch’属性为“false”(默认值是“true”)可以禁用这一特性。
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="fallbackToDefaultTypeMatch" value="false"/>
</bean>
正如上文所提到的,在解析标有@Resource注解的依赖时,Spring支持JNDI-lookup。如若要强制对所有使用@Resource注解的依赖进行JNDI lookup,那也只要将CommonAnnotationBeanPostProcessor的'alwaysUseJndiLookup' 标识设置为true就可以了(默认值是false)。
<bean class="org.springframework.context.annotation.CommonAnnotationBeanPostProcessor">
<property name="alwaysUseJndiLookup" value="true"/>
</bean>
另一个选择是,激活指定为‘resource-ref-mappings’的依据全局JNDI名的查找,在@Resource注解内提供‘mappedName’属性。即使目标对象实际上是一个JNDI资源,仍然推荐引入一个Spring管理对象,这样可以提供一个间接层并且因此降低耦合程度。自Spring2.0开始添加命名空间以来,定义一个委托Spring处理JNDI lookup的bean也变得愈发简练:
<jee:jndi-lookup id="dataSource" jndi-name="java:comp/env/jdbc/petclinic"/>
这个方法的优点在于间接层带来了巨大的部署弹性。比如说,一个单独的系统测试环境应该不再需要JNDI注册。在这种情况下,在系统测试配置中可以提供如下的bean定义:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
顺便提一下,上面的例子中,实际的JDBC连接属性从一个属性文件(properties file)解析而来,在这个属性文件里,关键字与提供的${占位符}互相对应,这需要注册一个名为PropertyPlaceholderConfigurer的BeanFactoryPostProcessor实现来完成。这是具体化那些属性(通常是针对特定环境的属性)常用的技术,这些属性可能比其他配置修改得更为频繁。
<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location" value="classpath:jdbc.properties"/>
</bean>
Srping2.5中新加入了‘context’命名空间,这个命名空间让我们能够得到更为简洁的方式来实现属性占位符(property placeholder)的配置:
<context:property-placeholder location="classpath:jdbc.properties"/>
生命周期注解:@PostConstruct和@PreDestroy
@PostConstruct 和@PreDestroy注解分别用来触发Spring的初始化和销毁回调。这个特性在原有基础上得到了扩展,但并没有替代在Spring2.5之前版本中提供的同样的回调的另两个选项。第一个选项是实现Spring的InitializingBean 和DisposableBean 接口中的一个或两个。这两个接口都需要一个回调方法的实现(分别是afterPropertiesSet()和destroy() )。这种基于接口的方法利用了Spring自动识别任何实现这些接口的Spring管理对象的能力,因而不再需要另外的配置。另一方面,Spring的一个关键目标是尽可能的非侵入。因此,许多Spring用户并不采用实现这些Spring特定接口的方法,而利用第二个选项,那就是提供他们自己的初始化和销毁方法。尽管入侵性小,但缺点在于使用这个方式的话就必须显式声明bean元素的init-method或destroy-method属性。显式配置有时候是必须的,例如当回调需要在开发人员控制能力之外的代码上被调用的时候。PetClinic应用程序很好地说明了这个场景。当它和JDBC配置一起运行的时候,会用到一个第三方DataSource,并且它显式声明了一个destroy-method。另外要注意到的是,单独的连接池数据源是dataSource的另一个部署选项,并且不需要修改任何代码。
<bean id="dataSource"
class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close"
p:driverClassName="${jdbc.driverClassName}"
p:url="${jdbc.url}"
p:username="${jdbc.username}"
p:password="${jdbc.password}"/>
在使用Spring2.5的过程中,如果一个对象需要调用一个初始化的回调方法的话,这个回调方法可以采用@PostConstruct来注解。例如一个假想的例子,一个后台任务需要在启动的时候就开始对一个文件目录进行轮询:
public class FilePoller {
@PostConstruct
public void startPolling() {
...
}
...
}
类似地,一个在Spring管理对象上用@PreDestroy注解的方法会在这个对象寄宿的应用程序上下文(application context)关闭的时候被调用。
public class FilePoller {
@PreDestroy
public void stopPolling() {
...
}
...
}
在添加了对JSR-250注解的支持以后,现在的Spring2.5结合前面提到的两种生命周期方法的长处。将@PostConstruct和@PreDestroy作为方法层注解加入,足可以实现在受Spring管理的上下文(context)中触发回调。换句话说,不需要另外基于XML的配置。同时,这两个注解是Java语言本身的一部分(甚至被包括在Java SE 版本6中),所以无需引入特定Spring包。这两个注解拥有在其他环境中也能理解的标识语义的优点,随着时间的推移,Java开发人员可能会发现这些注解在第三方开发库中被越来越多的运用到。最后,基于注解生命周期回调的其中一个有趣的结果是,不止一个方法可以带有这两个注解中的任何一个,并且所有注解了的方法会被调用。
激活刚刚描述的关于@Resource 、@PostConstruct和@PreDestroy注解的所有行为,正如上文提到的,需要为Spring的CommonAnnotationBeanPostProcessor提供一个bean定义。但另一个更简练的方法则可能是使用2.5中的新的context命名空间:
<context:annotation-config/>
引入这个单个元素将不单单注册一个CommonAnnotationBeanPostProcessor,也会像下文将叙述的那样激活自动装配(autowire)行为。CommonAnnotationBeanPostProcessor也为@WebServiceRef 和@EJB注解提供支持。这些将在本文系列的第三篇中和Spring2.5为企业集成提供的其他新特性一起讨论。
分享到:
相关推荐
Spring2.5的新特性-第一部分.doc 本文将主要关注于简化的配置和在Spring应用程序上下文(application context)核心新增的基于注解的功能; Spring_2.5新特性-第二部分-Spring_MVC中的新特性.doc
标题中的“spring2.5的一个新特性”指的Spring框架的第2.5版本中引入的重要更新。Spring是一个广泛使用的Java企业级应用开发框架,它提供了丰富的功能来简化应用程序的构建,包括依赖注入、面向切面编程(AOP)、...
Spring2.5版本是该框架的一个重要里程碑,它在2008年发布,带来了许多新特性和改进,提升了开发者在构建应用程序时的灵活性和效率。 **依赖注入(DI)和控制反转(IoC)** Spring的核心特性之一是依赖注入(Dependency...
整合这三个框架的第一步通常涉及到以下几个步骤: 1. 配置环境:确保项目中引入了Struts2、Spring和Hibernate的相应库,这通常通过Maven或Gradle等构建工具完成。 2. 配置Spring:创建Spring的配置文件(如`...
<br>新发布的Spring2.5继续坚持了这个发展趋向,特别是为那些使用Java 5或更新版本java的开发人员提供了进一步简化而强大的新特性。这些新特性包括:注解驱动的依赖性注入(annotation-driven dependency ...
- **版本历史**: Spring 2.5是Spring框架发展过程中的一个重要版本,相较于早期版本,它引入了许多新的特性以适应不断变化的开发需求和技术趋势。 #### 2. Spring的核心模块 - **IoC容器**: 提供了依赖注入功能,...
**第一章:Spring概述** 在这一章节,读者会了解到Spring框架的基本概念和其在企业级Java应用中的重要地位。Spring是一个轻量级、开源的Java应用框架,它以依赖注入(Dependency Injection,DI)和面向切面编程...
1. **依赖注入**:Spring的核心特性之一,它允许开发者在运行时将对象及其依赖关系进行解耦。通过XML配置或注解方式,Spring能够自动管理对象的创建和组装,降低了组件之间的耦合度,使得代码更加可测试和可维护。 ...
Spring框架是Java开发中的一个核心组件,尤其在企业级应用中广泛使用。Spring 2.5是其发展...教程还将涵盖如何设置开发环境、创建第一个Spring项目、配置bean、处理Web请求等基础步骤,为后续深入学习打下坚实基础。
在Spring2.5版本中,它引入了对Java 5特性的支持,如枚举、注解和泛型。核心特性包括IoC容器,允许开发者通过XML或注解进行bean的管理和装配;AOP用于实现跨切面的关注点,如日志、事务管理等。Spring2.5还加强了与...
1. **依赖注入(Dependency Injection, DI)**:DI是Spring的核心特性之一,它允许开发者将对象的创建和管理交给Spring容器,从而降低组件间的耦合度。通过XML配置、注解或者基于Java的配置方式,可以实现对象之间的...
- **Lazy Initialization**:可以使用 `lazy-init="true"` 来延迟 Bean 的初始化,这意味着只有在第一次请求 Bean 时才会进行初始化。 - **Default Lazy Initialization**:若希望对所有 Bean 都应用懒加载,则...
标题 "spring2.5 API 以及源代码" 涉及到的是Spring框架的一个较旧版本,即2.5版的API文档和源代码。Spring是Java开发中最广泛使用的轻量级框架,它极大地简化了企业级应用的开发。在这个版本中,Spring引入了许多...
- **快速入门**:介绍如何设置Spring环境,创建第一个Spring项目,并解释了基本的配置文件结构。 - **IoC容器**:深入解析IoC容器的工作原理,包括Bean的定义、实例化、初始化和销毁,以及Bean之间的依赖关系。 - ...
- 2.5版本加强了对Web服务的支持,包括WSDL第一类公民(First-Class WSDL)、JAXB2支持以及对WS-Security的改进。 9. **国际化(i18n)支持**: - 提供了更好的国际化支持,使得应用程序能够根据用户设置的语言...
在搭建Spring的运行环境中,我们需要创建一个新的项目,建立Spring的配置文件,引入必要的Spring库,并编写测试代码来验证配置是否正确。同时,接口的使用至关重要,因为它使得服务的提供者和消费者之间解耦。 在第...
Spring2.5版本是其发展的一个重要里程碑,引入了许多改进和新特性,使得开发者能够更加方便地进行依赖注入、事务管理、AOP(面向切面编程)等关键功能的实现。 在Spring框架中,依赖注入(Dependency Injection,...
"spring2.5"这个压缩包子文件的名称暗示了源码的主要部分可能与Spring框架有关,可能包含Spring配置文件(如 applicationContext.xml)、DAO和Service层的Java类,以及与Hibernate相关的配置文件(如 hibernate.cfg....
Spring MVC是Spring框架的一部分,提供了类似于Struts2的MVC实现。Spring的核心特性是DI,允许开发者在运行时动态地将对象组合在一起,降低了组件之间的耦合。AOP则允许我们编写关注点分离的代码,比如日志、事务...