Spring25的新特性第一部分.docx

上传人:b****4 文档编号:24524928 上传时间:2023-05-28 格式:DOCX 页数:31 大小:31.82KB
下载 相关 举报
Spring25的新特性第一部分.docx_第1页
第1页 / 共31页
Spring25的新特性第一部分.docx_第2页
第2页 / 共31页
Spring25的新特性第一部分.docx_第3页
第3页 / 共31页
Spring25的新特性第一部分.docx_第4页
第4页 / 共31页
Spring25的新特性第一部分.docx_第5页
第5页 / 共31页
点击查看更多>>
下载资源
资源描述

Spring25的新特性第一部分.docx

《Spring25的新特性第一部分.docx》由会员分享,可在线阅读,更多相关《Spring25的新特性第一部分.docx(31页珍藏版)》请在冰豆网上搜索。

Spring25的新特性第一部分.docx

Spring25的新特性第一部分

Spring2.5的新特性:

第一部分

从诞生之初,Spring框架就坚守它的宗旨:

简化企业级应用开发,同时给复杂问题提供强大的、非侵入性解决方案。

一年前发布的Spring2.0就把这些主题推到了一个新的高度。

XMLSchema的支持和自定义命名空间的使用大大减少了基于XML的配置。

使用Java5及更新版本java的开发人员如今可以利用植入了像泛型(generic)和注解等新语言特性的Spring库。

最近,和AspectJ表达式语言的紧密集成,使得以非侵入方式添加跨越定义良好的Spring管理对象分组的行为成为可能。

新发布的Spring2.5继续坚持了这个发展趋向,特别是为那些使用Java5或更新版本java的开发人员提供了进一步简化而强大的新特性。

这些新特性包括:

注解驱动的依赖性注入(annotation-drivendependencyinjection),使用注解而非XML元数据来自动侦测classpath上的Spring组件,注解对生命周期方法的支持,一个新的web控制器模型将请求映射到加注解的方法上,在测试框架中支持Junit4,SpringXML命名空间的新增内容,等等。

本文是探讨这些新特性的3篇系列文章中的第一篇。

本文将主要关注于简化的配置和在Spring应用程序上下文(applicationcontext)核心新增的基于注解的功能;第二篇文章将涵盖web层可用的新特性;最后一篇文章将着重介绍集成和测试的新增性能。

这一系列的三篇文章中引用的例子都基于SpringPetClinic应用程序范例。

此范例最近被重构以用于展示Spring最新功能,并被包含于Spring2.5的发布下载包中,可以从SpringFramework下载网页下载。

查看"samples/petclinic"目录下的"readme.txt"文件可以得知关于如何构建和部署PetClinic应用程序,掌握本文提到的新技术的最佳方法也许就是对PetClinic应用程序中所展示的特性进行试验。

Spring支持JSR-250注解

JavaEE5中引入了“Java平台的公共注解(CommonAnnotationsfortheJavaPlatform)”,而且该公共注解从JavaSE6一开始就被包含其中。

2006年5月,BEA系统宣布了他们在一个名为Pitchfork的项目上与Interface21的合作,该项目提供了基于Spring的JavaEE5编程模型的实现,包括支持用于注入(injection)、拦截(interception)和事务处理(transactions)的JSR-250注解和EJB3注解(JSR-220)。

在2.5版本中,Spring框架的核心(core)现在支持以下JSR-250注解:

Java代码

1.* @Resource  

2.* @PostConstruct  

3.* @PreDestroy  

*@Resource

*@PostConstruct

*@PreDestroy

结合Spring,这些注解在任何开发环境下都可以使用——无论是否有应用程序服务器——甚至是集成测试环境都可以。

激活这样的支持仅仅是注册一个单独的Springpost-processor的事情:

Java代码

1.  

2.  

@Resource注解

@Resource注解被用来激活一个命名资源(namedresource)的依赖注入,在JavaEE应用程序中,该注解被典型地转换为绑定于JNDIcontext中的一个对象。

Spring确实支持使用@Resource通过JNDIlookup来解析对象,默认地,拥有与@Resource注解所提供名字相匹配的“beanname(bean名字)”的Spring管理对象会被注入。

在下面的例子中,Spring会向加了注解的setter方法传递bean名为“dataSource”的Spring管理对象的引用。

Java代码

1.@Resource(name="dataSource")  

2. public void setDataSource(DataSource dataSource) {  

3.   this.dataSource = dataSource;  

4.}   

@Resource(name="dataSource")

publicvoidsetDataSource(DataSourcedataSource){

this.dataSource=dataSource;

}

直接使用@Resource注解一个域(field)同样是可能的。

通过不暴露setter方法,代码愈发紧凑并且还提供了域不可修改的额外益处。

正如下面将要证明的,@Resource注解甚至不需要一个显式的字符串值,在没有提供任何值的情况下,域名将被当作默认值。

Java代码

1.@Resource  

2.private DataSource dataSource; // inject the bean named 'dataSource'   

@Resource

privateDataSourcedataSource;//injectthebeannamed'dataSource'

该方式被应用到setter方法的时候,默认名是从相应的属性衍生出来,换句话说,命名为'setDataSource'的方法被用来处理名为'dataSource'的属性。

Java代码

1.private DataSource dataSource;  

2.@Resource  

3.public void setDataSource(DataSource dataSource) {  

4.   this.dataSource = dataSource;  

5.}   

privateDataSourcedataSource;

@Resource

publicvoidsetDataSource(DataSourcedataSource){

this.dataSource=dataSource;

}

当@Resource没有显式提供名字的时候,如果根据默认名字找不到对应的Spring管理对象,注入机制会回滚至类型匹配(type-match)。

如果刚好只有一个Spring管理对象符合该依赖的类型,那么它会被注入。

通过设置CommonAnnotationBeanPostProcessor的‘fallbackToDefaultTypeMatch’属性为“false”(默认值是“true”)可以禁用这一特性。

Java代码

1.  

2.     

3.   

正如上文所提到的,在解析标有@Resource注解的依赖时,Spring支持JNDI-lookup。

如若要强制对所有使用@Resource注解的依赖进行JNDIlookup,那也只要将CommonAnnotationBeanPostProcessor的'alwaysUseJndiLookup'标识设置为true就可以了(默认值是false)。

Java代码

1.  

2.     

3.  

另一个选择是,激活指定为‘resource-ref-mappings’的依据全局JNDI名的查找,在@Resource注解内提供‘mappedName’属性。

即使目标对象实际上是一个JNDI资源,仍然推荐引入一个Spring管理对象,这样可以提供一个间接层并且因此降低耦合程度。

自Spring2.0开始添加命名空间以来,定义一个委托Spring处理JNDIlookup的bean也变得愈发简练:

Java代码

1.

jndi-lookup id="dataSource" jndi-name="java:

comp/env/jdbc/petclinic"/>   

jndi-lookupid="dataSource"jndi-name="java:

comp/env/jdbc/petclinic"/>

这个方法的优点在于间接层带来了巨大的部署弹性。

比如说,一个单独的系统测试环境应该不再需要JNDI注册。

在这种情况下,在系统测试配置中可以提供如下的bean定义:

Java代码

1.

2.     p:

driverClassName="${jdbc.driverClassName}"  

3.     p:

url="${jdbc.url}"  

4.     p:

username="${jdbc.username}"  

5.     p:

password="${jdbc.password}"/>   

p:

driverClassName="${jdbc.driverClassName}"

p:

url="${jdbc.url}"

p:

username="${jdbc.username}"

p:

password="${jdbc.password}"/>

顺便提一下,上面的例子中,实际的JDBC连接属性从一个属性文件(propertiesfile)解析而来,在这个属性文件里,关键字与提供的${占位符}互相对应,这需要注册一个名为PropertyPlaceholderConfigurer的BeanFactoryPostProcessor实现来完成。

这是具体化那些属性(通常是针对特定环境的属性)常用的技术,这些属性可能比其他配置修改得更为频繁。

Java代码

1.  

2.   

jdbc.properties"/>  

3.   

jdbc.properties"/>

Srping2.5中新加入了‘context’命名空间,这个命名空间让我们能够得到更为简洁的方式来实现属性占位符(propertyplaceholder)的配置:

Java代码

1.

property-placeholder location="classpath:

jdbc.properties"/>  

property-placeholderlocation="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的另一个部署选项,并且不需要修改任何代码。

Java代码

1.

2.     class="mons.dbcp.BasicDataSource"  

3.     destroy-method="close"  

4.     p:

driverClassName="${jdbc.driverClassName}"  

5.     p:

url="${jdbc.url}"  

6.     p:

username="${jdbc.username}"  

7.     p:

password="${jdbc.password}"/>   

class="mons.dbcp.BasicDataSource"

destroy-method="close"

p:

driverClassName="${jdbc.driverClassName}"

p:

url="${jdbc.url}"

p:

username="${jdbc.username}"

p:

password="${jdbc.password}"/>

在使用Spring2.5的过程中,如果一个对象需要调用一个初始化的回调方法的话,这个回调方法可以采用@PostConstruct来注解。

例如一个假想的例子,一个后台任务需要在启动的时候就开始对一个文件目录进行轮询:

Java代码

1.public class FilePoller {  

2.   

3.   @PostConstruct  

4.   public void startPolling() {  

5.     ...  

6.   }  

7.   ...  

8.}   

publicclassFilePoller{

@PostConstruct

publicvoidstartPolling(){

...

}

...

}

类似地,一个在Spring管理对象上用@PreDestroy注解的方法会在这个对象寄宿的应用程序上下文(applicationcontext)关闭的时候被调用。

Java代码

1.public class FilePoller {  

2.   

3.   @PreDestroy  

4.   public void stopPolling() {  

5.     ...  

6.   }  

7.   ...  

8.}   

publicclassFilePoller{

@PreDestroy

publicvoidstopPolling(){

...

}

...

}

在添加了对JSR-250注解的支持以后,现在的Spring2.5结合前面提到的两种生命周期方法的长处。

将@PostConstruct和@PreDestroy作为方法层注解加入,足可以实现在受Spring管理的上下文(context)中触发回调。

换句话说,不需要另外基于XML的配置。

同时,这两个注解是Java语言本身的一部分(甚至被包括在JavaSE版本6中),所以无需引入特定Spring包。

这两个注解拥有在其他环境中也能理解的标识语义的优点,随着时间的推移,Java开发人员可能会发现这些注解在第三方开发库中被越来越多的运用到。

最后,基于注解生命周期回调的其中一个有趣的结果是,不止一个方法可以带有这两个注解中的任何一个,并且所有注解了的方法会被调用。

激活刚刚描述的关于@Resource、@PostConstruct和@PreDestroy注解的所有行为,正如上文提到的,需要为Spring的CommonAnnotationBeanPostProcessor提供一个bean定义。

但另一个更简练的方法则可能是使用2.5中的新的context命名空间:

Java代码

1.

annotation-config/>  

annotation-config/>

引入这个单个元素将不单单注册一个CommonAnnotationBeanPostProcessor,也会像下文将叙述的那样激活自动装配(autowire)行为。

CommonAnnotationBeanPostProcessor也为@WebServiceRef和@EJB注解提供支持。

这些将在本文系列的第三篇中和Spring2.5为企业集成提供的其他新特性一起讨论。

利用注解来优化细粒度自动装配

涵盖Spring对自动装配支持的文档中常常会提到由于自动装配机制的粗粒度而伴随有很多限制性。

Spring2.5之前,自动装配可以通过很多不同的方式来配置:

构造器,类型setter,名字setter,或者自动侦测(在该方式中Spring选择自动装配一个构造器或者类型setter)。

这些不同的选择确实提供了很大程度的灵活性,但它们中没有一个方法能够提供细粒度控制。

换句话说,Spring2.5之前还不可能自动装配某个对象setter方法的特定子集,或者通过类型或名字来自动装配它的一些属性。

结果,许多Spring用户意识到将自动装配应用到构建原型和测试中的好处,但当提到在产品中维护和支持系统时,大部分人认为,加入冗长的显式配置对于澄清它所担负的职责是非常值得的。

然而,Spring2.5大幅度地改变了布局。

如上文所述,自动配置选项现在已经被扩展,支持JSR-250@Resource注解来激活在每个方法或域基础上被命名资源的自动装配。

然而,@Resource注解若单独使用的话有很多限制。

因此,Sring2.5引进了一个名为@Autowired的注解进一步提高控制级别。

为激活这里所讲的行为需要注册一个单独的bean定义:

Java代码

1.  

另外如上文提到的,context命名空间提供了一个更简明的方法。

它将激活本文所讨论的两个post-processor(AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor)和我们在Spring2.0中引入的基于注解的post-processor:

RequiredAnnotationBeanPostProcessor和PersistenceAnnotationBeanPostProcessor。

Java代码

1.

annotation-config/>  

annotation-config/>

利用@Autowired注解可以对相应类型注入依赖。

域、构造器和方法都可以激活此行为。

实际上,aotowired方法并不一定要是setter方法,且可以接受多个参数。

下面这个例子是完整的可接受的用法:

Java代码

1.@Autowired  

2.public void setup(DataSource dataSource, AnotherObject o) { ... }   

@Autowired

publicvoidsetup(DataSourcedataSource,AnotherObjecto){...}

默认地,标有@Autowired注解的依赖被认为是必须的。

然而,也可以将required属性值设置为false来声明它们中的任何一个。

在下面这个例子中,DefaultStrategy只有在context命名空间中没有SomeStrategy类型的Spring管理对象时才能被使用。

Java代码

1.@Autowired(required=false)  

2.private SomeStrategy strategy 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 人文社科 > 哲学历史

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1