Spring 2.5的新功能:第1部分

介绍

自成立以来,Spring框架一直致力于简化企业应用程序开发的目标,同时为复杂的问题提供强大的,非侵入式的解决方案。 一年多以前,随着Spring 2.0的发布,这些主题进一步发展。 XML Schema支持和自定义名称空间减少了基于XML的配置量。 使用Java 5或更高版本的开发人员能够利用Spring库,这些库利用了新的语言功能,例如泛型和注释。 与AspectJ的表达语言紧密集成,可以跨定义良好的Spring管理对象组对行为进行非侵入式添加。

新发布的Spring 2.5通过提供进一步的简化和强大的新功能(尤其是对于那些使用Java 5或更高版本的用户)来延续这一趋势。 这些功能包括注释驱动的依赖项注入,使用注释而不是XML的元数据在类路径上自动检测Spring组件,对生命周期方法的注释支持,用于将请求映射到注释方法的新的Web控制器模型,对Junit 4的支持。测试框架,Spring XML名称空间的新增功能等。

本文是探讨这些新功能的三部分系列文章的第一篇。 本文将重点介绍Spring应用程序上下文核心中的简化配置和基于注释的新功能。 第二篇文章将介绍Web层中可用的新功能,而最后一篇文章将重点介绍可用于集成和测试的其他功能。 本系列文章中描述的大多数示例都基于Spring PetClinic示例应用程序。 该示例最近已进行重构,以展示最新的Spring功能,并包含在Spring Framework下载页面上的Spring 2.5发行版中 。 查看“ samples / petclinic”目录中的“ readme.txt”文件,以获取有关构建和部署PetClinic应用程序的说明。 对PetClinic应用程序中展示的功能进行实验可能是掌握此处讨论的新技术的最佳方法。

Spring对JSR-250注释的支持

Java EE版本5引入了“ Java平台的通用注释”,并且从Java SE版本6开始就包含了“ Java通用注释”。2006年5月,BEA Systems 宣布与Interface21 合作开发名为Pitchfork的项目。提供了Java EE 5编程模型的基于Spring的实现,其中包括对JSR-250批注和EJB 3批注(JSR-220)的支持,以用于注入,拦截和事务处理。 从2.5版开始,Spring Framework 核心现在支持以下JSR-250注释:

  • @资源
  • @PostConstruct
  • @PreDestroy

使用Spring,无论在有无应用程序服务器的任何环境中,甚至在集成测试中,都支持这些注释。 启用此支持只需注册一个Spring后处理器即可:

<bean class = "org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" /> 

@Resource批注

@Resource批注启用“命名资源”的依赖项注入。 在Java EE应用程序中,通常将其转换为绑定到JNDI上下文的对象。 Spring确实支持使用@Resource通过JNDI查找来解析对象,但是默认情况下,将注入其“ bean名称”与提供给@Resource批注的名称匹配的Spring托管对象。 在下面的示例中,Spring将对bean名为“ dataSource”的Spring管理对象的引用传递给带注释的setter方法。

@Resource(name="dataSource") 
public void setDataSource(DataSource dataSource) {
this . dataSource = dataSource;
}

也可以直接使用@Resource注释字段。 通过不公开setter方法,代码更加简洁,还提供了增强不变性的其他好处。 如下所示, @ Resource注释甚至不需要显式的String值。 如果未提供任何内容,那么该字段的名称将用作默认名称。

@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管理对象,则注入机制将回退到类型匹配。 如果恰好有一个与依赖项类型匹配的Spring管理对象,则将其注入。 可以通过将CommonAnnotationBeanPostProcessor'fallbackToDefaultTypeMatch'属性设置为'false'来禁用此功能(默认情况下为'true')。

<bean class = "org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" > 
<property name = "fallbackToDefaultTypeMatch" value = "false" />
</bean>

如上所述,当解析使用@Resource注释的依赖项时,Spring确实提供了对JNDI查找的支持。 要强制使用@Resource注解的所有依赖直接JNDI查找,设置CommonAnnotationBeanPostProcessor会“alwaysUseJndiLookup”标志为“真”(这是“假”默认情况下)。

<bean class = "org.springframework.context.annotation.CommonAnnotationBeanPostProcessor" > 
<property name = "alwaysUseJndiLookup" value = "true" />
</bean>

或者,要启用基于指定为'resource-ref-mappings'的全局JNDI名称的查找,请在@Resource批注内提供'mappedName'属性。 即使目标对象实际上是JNDI资源,建议的做法仍然是引用Spring管理的对象,从而提供一定程度的间接访问,从而降低耦合程度。 从Spring 2.0开始,有了可用的名称空间添加,委派给Spring以处理JNDI查找的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连接属性是从属性文件中解析的,其中的键与提供的$ {placeholder}令牌匹配。 这是通过注册一个名为PropertyPlaceholderConfigurer的Spring BeanFactoryPostProcessor实现来实现的。 这是用于外部化那些属性(通常是特定于环境的属性)的常用技术,这些属性可能需要比其余配置更频繁地进行更改。

<bean class = "org.springframework.beans.factory.config.PropertyPlaceholderConfigurer" > 
<property name = "location" value = "classpath:jdbc.properties" />
</bean>

在Spring 2.5中添加了“ context”名称空间后,可以使用更简洁的方法来替代属性占位符配置:

<context:property-placeholder location = "classpath:jdbc.properties" /> 

生命周期注释:@PostConstruct和@PreDestroy

@PostConstruct@PreDestroy批注可以分别用于触发Spring初始化和销毁​​回调。 该功能得到了扩展,但不能替代在2.5之前的Spring版本中提供此类回调的两个选项。 第一种选择是实现Spring的InitializingBeanDisposableBean接口中的一个或两个。 这些接口中的每个接口都需要一个回调方法实现(分别为afterPropertiesSet()destroy() )。 基于接口的方法利用了Spring自动识别实现这些接口的任何Spring管理对象的能力,因此不需要任何额外的配置。 另一方面,Spring的主要目标是尽可能地避免侵入性。 因此,许多Spring用户没有实现特定于Spring的接口,而是利用了第二种方法,即提供自己的初始化和销毁​​方法。 尽管侵入性较小,但该方法的缺点是它需要在“ bean”元素上显式声明“ init-method”和/或“ destroy-method”属性。 有时必须进行显式配置,例如,当需要在开发人员无法控制的代码上调用回调时。 PetClinic应用程序演示了这种情况。 当使用其JDBC配置运行它时,将使用第三方数据源 ,并明确声明一个“销毁方法” 。 还要注意的是,独立的连接池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}" />

在Spring 2.5中,如果对象需要在初始化时调用回调方法,则可以使用@PostConstruct注释对该方法进行注释。 例如,假设有一个后台任务需要在启动时开始轮询文件目录。

public class FilePoller {

@PostConstruct
public void startPolling() {
...
}
...
}

同样,在托管该对象的应用程序上下文关闭时,将调用在Spring管理的对象上以@PreDestroy注释的方法。

public class FilePoller {

@PreDestroy
public void stopPolling() {
...
}
...
}

通过增加对JSR-250批注的支持,Spring 2.5现在结合了其先前两个生命周期方法替代方案的优点。 将@PostConstruct@PreDestroy添加为方法级别的注释足以在Spring托管上下文中触发回调。 换句话说,不需要其他基于XML的配置。 同时,注释是Java语言本身的一部分(甚至从版本6开始甚至包含在Java SE中),因此不需要特定于Spring的导入。 注释具有指示在其他环境中应理解的语义的附加好处,并且随着时间的流逝,Java开发人员可能会期望看到第三方库中使用这些注释的频率更高。 最后,基于注释的生命周期回调的一个有趣的结果是, 不止一种方法可以承载任一注释,并且所有带注释的方法都将被调用。

为了启用上述针对@Resource ,@ PostConstruct@PreDestroy批注的所有行为,请为Spring的CommonAnnotationBeanPostProcessor提供单个bean定义,如前所示。 2.5中新的“ context”名称空间甚至可以提供更为简洁的选项:

<context:annotation-config/> 

包括该单个元素不仅将注册CommonAnnotationBeanPostProcessor ,而且还将启用自动装配行为,如下节所述。 CommonAnnotationBeanPostProcessor甚至提供对@WebServiceRef@EJB注释的支持。 这些将在本系列的第三篇文章中以及其他用于企业集成的Spring 2.5新功能中讨论。

带注释的细粒度自动装配

由于自动装配机制的粗粒度,涵盖Spring对自动装配的支持的文档经常伴随着警告。 在Spring 2.5之前,可以为许多不同的方法配置自动装配:构造函数,按类型设置的设置器,按名称设置的设置器或自动检测(Spring选择在其中自动构造器或按类型设置的设置器)。 这些各种选项的确提供了很大程度的灵活性,但是它们都不提供非常精细的控制。 换句话说,在Spring 2.5之前,无法自动连接对象的setter方法的特定子集,也无法通过类型自动连接对象的某些属性,而通过名称自动连接对象的某些属性。 结果,许多Spring用户已经认识到自动装配对原型开发和测试的好处,但是在维护和支持生产中的系统时,大多数人都认为显式配置的附加详细信息很值得其提供。

但是,Spring 2.5极大地改变了环境。 如上所述,现在已经通过支持JSR-250 @Resource注释扩展了自动装配选项,从而可以按方法或按字段自动装配命名资源。 但是,仅@Resource注释确实有一些限制。 因此,Spring 2.5引入了@Autowired注释,以进一步提高控制级别。 要启用本节中描述的行为,请注册一个bean定义:

<bean class = "org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" /> 

另外,“上下文”命名空间提供了一个更简洁的选择,如前所示。 这将使这篇文章(AutowiredAnnotationBeanPostProcessorCommonAnnotationBeanPostProcessor会 ),以及在Spring 2.0中引入的基于注解的后处理器中所讨论的两个后置处理器:RequiredAnnotationBeanPostProcessorPersistenceAnnotationBeanPostProcessor。

<context:annotation-config/> 

使用@Autowired批注,可以注入按类型匹配的依赖项。 已为字段,构造函数和方法启用此行为。 实际上,自动装配方法不必是“设置”方法,甚至可以接受多个参数。 以下是完全可以接受的:

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

默认情况下,标有@Autowired批注的依赖项将按要求处理。 但是,也可以通过将'required'属性设置为'false'来将它们声明为可选。 在下面的例子中,如果类型SomeStrategy Spring管理对象的上下文中发现DefaultStrategy将被使用。

@Autowired(required=false) 
private SomeStrategy strategy = new DefaultStrategy();

当Spring上下文包含多个期望类型的对象时,按类型自动装配显然会导致歧义。 默认情况下,如果对于所需的依赖项没有一个确切的bean,自动装配机制将失败。 同样,对于任何可选属性,如果有多个候选项可用,则它将失败(如果可选且零候选可用,则它将简单地跳过该属性)。 有许多配置选项可避免这些冲突。

当上下文中有给定类型的一个实例时,该类型的bean定义应包含'primary'属性。 当上下文中可能有其他实例可用时,此方法效果很好,但始终会显式配置那些非主要实例。

<bean id = "dataSource" primary="true" ... /> 

当需要更多控制时,可以使用@Qualifier注释进一步注释任何自动装配的字段,构造函数参数或方法参数。 限定符可以包含String值,在这种情况下,Spring将尝试按名称进行匹配。

@Autowired
@Qualifier("primaryDataSource")
private DataSource dataSource;

@Qualifier作为单独的注释存在的主要原因是,可以在构造函数或方法本身上使用@Autowired注释的同时, 其应用于构造函数参数或方法参数的级别。

@Autowired
public void setup( @Qualifier("primaryDataSource") DataSource dataSource, AnotherObject o) { ... }

@Qualifier是单独的注释这一事实为定制提供了更多好处。 用户定义的注释也可以在自动装配过程中扮演限定符的角色。 实现此目的的最简单方法是使用@Qualifier本身作为元注释来注释自定义注释。

@Target({ElementType.FIELD , ElementType. PARAMETER , ElementType. TYPE , ElementType. ANNOTATION_TYPE })
@Retention(RetentionPolicy. RUNTIME )
@Qualifier
public @interface VetSpecialty { ... }

自定义注释可以可选地包括一个用于按名称匹配的值,但更常见的是将其用作“标记”注释或定义一个为限定符过程提供更多含义的值。 例如,下面的摘录描述了一个字段,该字段应与按类型匹配的候选人中的合格候选人自动联系起来。

@Autowired
@VetSpecialty("dentistry")
private Clinic dentistryClinic;

当使用XML配置作为此依赖关系解决方案的目标时,可以将'qualifier'子元素添加到bean定义中。 在有关组件扫描的下一部分中,将介绍一种非XML的替代方法。

<bean id = "dentistryClinic" class = "samples.DentistryClinic" > 
<qualifier type = "example.VetSpecialty" value = "dentistry" />
</bean>

为了避免对@Qualifier注释的任何依赖,请在Spring上下文中提供CustomAutowireConfigurer bean定义,然后直接注册任何定制注释类型:

<bean class = "org.springframework.beans.factory.annotation.CustomAutowireConfigurer" > 
<property name = "customQualifierTypes" >
<set>
<value> example.VetSpecialty </value>
</set>
</property>
</bean>

现在已经明确声明了自定义限定符,不再需要@Qualifier元注释。

@Target({ElementType.FIELD , ElementType. PARAMETER , ElementType. TYPE , ElementType. ANNOTATION_TYPE })
@Retention(RetentionPolicy. RUNTIME )
public @interface VetSpecialty { ... }

在相关说明中,甚至可以在配置AutowiredAnnotationBeanPostProcessor时替换@Autowired注释本身。

<bean class = "org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor" > 
<property name = "autowiredAnnotationType" value = "example.Injected" />
</bean>

在大多数情况下,定义自定义“标记”注释以及按名称或其他语义值进行匹配的选项的能力应足以实现对自动装配过程的细粒度控制。 但是,Spring还支持对限定符批注中任意数量的任意属性的支持。 例如,以下是非常精细的限定符的假设示例。

@SpecializedClinic(species="dog", breed="poodle") 
private Clinic poodleClinic;

定制限定符实现将定义那些属性。

@Target({ElementType.FIELD , ElementType. PARAMETER , ElementType. TYPE , ElementType. ANNOTATION_TYPE })
@Retention(RetentionPolicy. RUNTIME )
@Qualifier
public @interface SpecializedClinic {

String species();

String breed();

}

然后,定制限定符的属性可以与bean定义的XML中“限定符”注释的“属性”子元素匹配。 这些元素用于提供键/值对。

<bean id = "poodleClinic" class = "example.PoodleClinic" > 
<qualifier type = "example.SpecializedClinic" >
<attribute key = "species" value = "dog" />
<attribute key = "breed" value = "poodle" />
</qualifier>
</bean>

到目前为止,所有展示的自动装配都是针对单个实例的,但是也支持集合。 只要有必要在上下文中获取所有某种类型的Spring管理对象,只需将@Autowired批注添加到强类型的Collection中。

@Autowired
private List<Clinic> allClinics ;

在本节中值得指出的最后一项功能是使用自动装配代替Spring的“ Aware”接口。 在Spring 2.5之前,如果对象需要引用Spring上下文的ResourceLoader ,则它可以实现ResourceLoaderAware,从而允许Spring通过setResourceLoader(ResourceLoader resourceLoader)方法提供此依赖关系。 相同的技术适用于获取对Spring管理的MessageSource甚至ApplicationContext本身的引用。 对于Spring 2.5用户,现在可以通过自动装配完全支持此行为(请注意,应始终仔细考虑将这些特定于Spring的依赖项包括在内,并且通常仅在明显与业务逻辑分离的“基础结构”代码中使用)。

@Autowired
private MessageSource messageSource;

@Autowired
private ResourceLoader resourceLoader;

@Autowired
private ApplicationContext applicationContext;

弹簧元件的自动检测

从2.0版开始,Spring引入了“定型”注释的概念,其中@Repository注释用作数据访问代码的标记。 Spring 2.5添加了两个新的注释- @ Service@Controller-以完成常见的三层体系结构(数据访问对象,服务和Web控制器)的角色指定。 Spring 2.5还引入了其他构造型在逻辑上扩展的通用@Component注释。 通过清楚地指示应用程序角色,这些构造型促进了Spring AOP和后处理器的使用,以便基于这些角色为带注释的对象提供其他行为。 例如,Spring 2.0引入了PersistenceExceptionTranslationPostProcessor,以自动为任何带有@Repository批注的对象启用数据访问异常转换。

这些相同的注释也可以与Spring 2.5的另一个新功能结合使用:自动检测类路径上的组件。 尽管XML传统上一直是Spring元数据最流行的格式,但它不是唯一的选择。 实际上,Spring容器的内部元数据表示形式是纯Java,当使用XML定义Spring管理的对象时,这些定义将在实例化过程之前解析并转换为Java对象。 Spring 2.5的一项重要新功能是支持从源代码级注释中读取该元数据。 到目前为止,所描述的自动装配机制利用注释元数据来注入依赖关系,但是仍然需要注册至少一个最小的“ bean定义”,以便提供每个Spring管理对象的实现类。 组件扫描功能甚至不需要XML中的最小bean定义。

如上所示,Spring的注释驱动自动装配可以在不牺牲细粒度控制的情况下显着减少XML的数量。 组件检测机制使这一点更进一步。 不必完全取代XML中的配置,而是可以将组件扫描与XML元数据一起操作以简化整体配置。 将XML与注释驱动技术相结合的这种可能性可以导致一种均衡的方法,如PetClinic示例应用程序的2.5版本所证明的。 在那里,基础结构组件(数据源,事务管理器等)以XML以及如上所述的外部化属性进行定义。 数据访问层对象也部分地用XML定义,但是它们的配置也利用@Autowired注释简化了依赖项的注入。 最后,根本没有在XML中明确定义Web层的“控制器”。 而是使用以下配置来触发所有Web控制器的自动检测:

<context:component-scan base-package = "org.springframework.samples.petclinic.web" /> 

注意,提供了“ base-package”属性。 组件扫描的默认匹配规则将递归地检测该包中类上的任何Spring构造型注释(可以在逗号分隔的列表中提供多个包)。 因此,PetClinic示例应用程序的各种控制器实现都使用@Controller (Spring的内置构造型之一 )进行注释。 这是一个例子:

@Controller 
public class ClinicController {

private final Clinic clinic ;

@Autowired
public ClinicController(Clinic clinic) {
this . clinic = clinic;
}
...

自动检测的组件会在Spring容器中注册,就像它们是用XML定义的一样。 如上所述,这些对象可以依次使用注释驱动的自动装配。

组件扫描器的匹配规则也可以使用过滤器进行自定义,以基于类型,注释,AspectJ表达式或名称模式的正则表达式来包括或排除组件。 也可以禁用默认构造型。 例如,测试配置可以忽略默认构造型,而是自动检测名称以Stub开头或包含@Mock注释的任何类:

<context:component-scan base-package = "example" use-default-filters = "false" > 
<context:include-filter type = "aspectj" expression = "example..Stub*" />
<context:include-filter type = "annotation" expression = "example.Mock" />
</context:component-scan>

类型匹配限制也可以使用排除过滤器进行控制。 例如,要依赖@Repository批注之外的默认过滤器,请添加exclude-filter

<context:component-scan base-package = "example" > 
<context:exclude-filter type = "annotation" expression = "org.springframework.stereotype.Repository" />
</context:component-scan>

显然,可以通过多种方式扩展组件扫描以注册您自己的自定义类型。 构造型注释是最简单的选择,因此构造型概念本身就是可扩展的。 如前所述, @Component@Repository@ Service@Controller批注“逻辑上”扩展的通用 构造型指示符。 碰巧的是, @ Component可以作为元注释(即在另一个注释上声明的注释)提供,并且具有@Component元注释的任何自定义注释都将由扫描程序的默认匹配规则自动检测到。 一个例子有望表明,这比听起来简单得多。

回忆一下上面部分中介绍@PostConstruct@PreDestroy生命周期注释的假设背景任务。 一个应用程序可能有许多这样的后台任务,这些任务实例通常需要XML Bean定义才能在Spring上下文中注册并在适当的时间调用其生命周期方法。 使用组件扫描,不再需要那些显式的XML bean定义。 如果所有后台任务都实现相同的接口或遵循命名约定,则可以使用include-filters 。 但是,一种更简单的方法是为这些任务对象创建注释,并提供@Component元注释。

@Target({ElementType.TYPE })
@Retention(RetentionPolicy. RUNTIME )
@Documented
@Component
public @interface BackgroundTask {
String value() default "" ;
}

然后在任何后台任务的类定义中提供自定义构造型注释。

@BackgroundTask 
public class FilePoller {

@PostConstruct
public void startPolling() {
...
}

@PreDestroy
public void stopPolling() {
...
}
...
}

可以像以前一样轻松地提供通用@Component注释,但是自定义注释技术为使用有意义的特定于域的名称提供了机会。 这些特定于域的注释随后提供了更多机会,例如使用AspectJ切入点表达式来识别所有后台任务,以添加监视那些任务活动的建议。

默认情况下,当检测到一个组件时,Spring将使用非限定的类名自动生成一个“ bean名称”。 在前面的示例中,生成的bean名称将为“ filePoller”。 然而,对于被注释与被注释与Spring的典型化注解(@Component,@Repository,@Service@Controller) 其他任何注解之一的任何类@Component在作为元注解(如@BackgroundTask上面的示例),可以为构造型注释明确指定“值”属性,然后将该实例注册到上下文中,并将该值作为其“ bean名称”。 在以下示例中,名称将为“ petClinic”,而不是默认生成的名称“ simpleJdbcClinic”。

@Service("petClinic") 
public class SimpleJdbcClinic {
...
}

同样,为以下修订版本的FilePoller生成的bean名称将是“ poller”而不是“ filePoller”。

@BackgroundTask("poller") 
public class FilePoller {
...
}

虽然默认情况下将所有Spring管理的对象都视为单例实例,但有时有必要为对象指定备用“作用域”。 例如,在Web层中,Spring管理的对象可以绑定到“请求”或“会话”范围。 从2.0版开始,Spring的范围机制甚至是可扩展的,因此可以向应用程序上下文注册自定义范围。 在XML配置中,只需包含“ scope”属性和范围名称即可。

<bean id = "shoppingCart" class = "example.ShoppingCart" scope= "session" > 
...
</bean>

使用Spring 2.5,可以通过提供@Scope批注对扫描的组件完成相同的操作。

@Component
@Scope("session")
public class ShoppingCart {
...
}

这里要解决的最后一个主题是使用组件扫描时简化限定符注释。 在上一节中,以下对象用作带有自定义限定符注释的自动装配的示例:

@VetSpecialty("dentistry") 
private Clinic dentistryClinic ;

然后,该示例将XML内的“ qualifier”元素用于该依赖关系的预期目标bean定义上。 使用组件扫描时,不需要XML元数据。 而是,可以将自定义限定符作为类型级别的注释包含在目标类定义中。 因此,将扫描的@Repository实例作为依赖项的替代示例如下所示:

@Repository
@VetSpecialty("dentistry")
public class DentistryClinic implements Clinic {
...
}

最后,对于前面的示例,该示例具有带有属性的定制限定符注释,该依赖项目标的非XML等效项是:

@Repository
@SpecializedClinic(species="dog", breed="poodle")
public class PoodleClinic implements Clinic {
...
}

结论

Spring 2.5在许多领域提供了重要的新功能。 本文的主要重点是通过利用Java注释的功能来简化配置。 Spring支持JSR-250中定义的“通用注释”,同时提供附加注释,以更精细地控制自动装配过程。 Spring 2.5还扩展了从Spring 2.0的@Repository开始的'stereotype'注释,并且所有这些原型都可以与新的组件扫描功能结合使用。 仍然完全支持基于XML的配置,并且Spring 2.5引入了新的“上下文”名称空间,该名称空间为常见的配置方案提供了更简洁的语法。 实际上,对将XML和基于注释的配置无缝结合的支持使整体方法可以达到均衡。 可以在模块化XML文件中定义基础结构的复杂配置,而应用程序堆栈的逐渐更高的层可以受益于更多基于注释的技术-所有这些都在同一Spring 2.5应用程序上下文中进行。

请继续关注本系列的下一篇文章,它将介绍Spring Web层中基于注释的强大功能。

翻译自: https://www.infoq.com/articles/spring-2.5-part-1?topicPageSponsorship=c1246725-b0a7-43a6-9ef9-68102c8d48e1

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值