利用注解来优化细粒度自动装配
涵盖Spring对自动装配支持的文档中常常会提到由于自动装配机制的粗粒度而伴随有很多限制性。Spring2.5之前,自动装配可以通过很多不同的方式来配置:构造器,类型setter,名字setter,或者自动侦测(在该方式中Spring选择自动装配一个构造器或者类型setter)。这些不同的选择确实提供了很大程度的灵活性,但它们中没有一个方法能够提供细粒度控制。换句话说,Spring2.5之前还不可能自动装配某个对象setter方法的特定子集,或者通过类型或名字来自动装配它的一些属性。结果,许多Spring用户意识到将自动装配应用到构建原型和测试中的好处,但当提到在产品中维护和支持系统时,大部分人认为,加入冗长的显式配置对于澄清它所担负的职责是非常值得的。
然而,Spring2.5大幅度地改变了布局。如上文所述,自动配置选项现在已经被扩展,支持JSR-250 @Resource注解来激活在每个方法或域基础上被命名资源的自动装配。然而,@Resource注解若单独使用的话有很多限制。因此,Sring2.5引进了一个名为@Autowired的注解进一步提高控制级别。为激活这里所讲的行为需要注册一个单独的bean定义:
<bean class="org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"/>
另外如上文提到的,context命名空间提供了一个更简明的方法。它将激活本文所讨论的两个post-processor(AutowiredAnnotationBeanPostProcessor和CommonAnnotationBeanPostProcessor)和我们在Spring2.0中引入的基于注解的post-processor:RequiredAnnotationBeanPostProcessor和PersistenceAnnotationBeanPostProcessor。
<context:annotation-config/>
利用@Autowired 注解可以对相应类型注入依赖。域、构造器和方法都可以激活此行为。实际上,aotowired方法并不一定要是setter方法,且可以接受多个参数。下面这个例子是完整的可接受的用法:
@Autowired
public void setup(DataSource dataSource, AnotherObject o) { ... }
默认地,标有@Autowired注解的依赖被认为是必须的。然而,也可以将required属性值设置为false来声明它们中的任何一个。在下面这个例子中,DefaultStrategy只有在context命名空间中没有SomeStrategy类型的Spring管理对象时才能被使用。
@Autowired(required=false)
private SomeStrategy strategy = new DefaultStrategy();
通过类型进行的自动装配明显地在Spring context包含多于一个期望类型的对象的时候造成歧义。默认地,如果一个必须的依赖没不是恰好一个bean与之对应的话,自动装配机制就会失败。同样的,对于任何一个可选属性,如果它拥有一个以上的候选,也都会失败(如果属性可选且没有任何候选可用的话,该属性则会被简单地跳过)。有很多不同的配置选项可以避免这些冲突。
若Context中拥有一个指定类型的一个主关键实例,对这个类型定义的bean定义应该包含‘primary’属性。当Context中含有其他可用实例的时候这个方法就很适用,但那些非主关键实例总是显式配置的。
<bean id="dataSource" primary="true" ... />
在需要更多控制的时候,任何autowired的域、构造参数、或者方法参数可以进一步加注@Qualifier注解。qualifier可以包含一个字符串值,在这种情况下,Spring会试图通过名字来找到对应的对象。
@Autowired
@Qualifier("primaryDataSource")
private DataSource dataSource;
@Qualifier作为一个独立注解存在的主要原因是它可以被应用在构造器参数或方法参数上,但上文提到的@Autowired注解只能运用在构造器或方法本身。
@Autowired
public void setup(@Qualifier("primaryDataSource") DataSource dataSource, AnotherObject o) { ... }
事实上,@Qualifier作为一个单独的注解在定制化方面提供了更多的好处。用户自定义的注解在自动装配过程中也可以起到qualifier的作用,最简单的实现方式是在运用自定义注解的同时将@Qualifier作为它的元注解。
@Target({ElementType.FIELD, ElementType.PARAMETER, ElementType.TYPE, ElementType.ANNOTATION_TYPE})
@Retention(RetentionPolicy.RUNTIME)
@Qualifier
public @interface VetSpecialty { ... }
自定义注解可以选择包含一个值来提供通过名字匹配的功能,但更普遍的用法是将它作为“标记”注解或定义一个对qualifier过程提供一些更多含义的值。例如,下面这个摘录则描绘了一个域,它应该和通过名字匹配得到的结果中合格的对象进行自动装配。
@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 context中提供一个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还支持在qualifier注解上任意数目的任意属性。比如,下面是一个极为细粒度修饰的例子。
@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();
}
自定义修饰符属性可以匹配那些XML中bean定义的qualifier注解的属性子元素。这些元素通常以键/值对方式提供。
<bean id="poodleClinic" class="example.PoodleClinic">
<qualifier type="example.SpecializedClinic">
<attribute key="species" value="dog"/>
<attribute key="breed" value="poodle"/>
</qualifier>
</bean>
目前为止,关于autowire的描述都只是针对单独的实例,其实也支持集合。在任何需要得到所有context中某种特定类型的Spring管理对象的时候,只需要简单地在一个强类型(strongly-typed)集合上加注@Autowired 注解。
@Autowired
private List<Clinic> allClinics;
本章节最后一个值得指出的特性是自动装配的使用替代了Spring的Aware接口。在Spring2.5之前,如果某个对象需要一个Spring context的ResourceLoader的引用,它可以通过实现ResourceLoaderAware的方式使得Spring通过setResourceLoader(ResourceLoader resourceLoader)方法来提供该依赖。借助同样的方法可以得到Spring管理的MessageSource的引用,甚至可以得到ApplicationContext本身。对于Spring2.5用户而言,这个行为现在通过autowiring得到全面支持(需要指出的是包含这些Spring特定依赖的时候应该考虑周到,特别是它们只能用于从业务逻辑清楚地分割出来的基础构架代码中)。
@Autowired
private MessageSource messageSource;
@Autowired
private ResourceLoader resourceLoader;
@Autowired
private ApplicationContext applicationContext;
分享到:
相关推荐
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能够自动管理对象的创建和组装,降低了组件之间的耦合度,使得代码更加可测试和可维护。 ...
在Spring2.5版本中,它引入了对Java 5特性的支持,如枚举、注解和泛型。核心特性包括IoC容器,允许开发者通过XML或注解进行bean的管理和装配;AOP用于实现跨切面的关注点,如日志、事务管理等。Spring2.5还加强了与...
Spring框架是Java开发中的一个核心组件,尤其在企业级应用中广泛使用。Spring 2.5是其发展...教程还将涵盖如何设置开发环境、创建第一个Spring项目、配置bean、处理Web请求等基础步骤,为后续深入学习打下坚实基础。
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引入了许多...
- 2.5版本加强了对Web服务的支持,包括WSDL第一类公民(First-Class WSDL)、JAXB2支持以及对WS-Security的改进。 9. **国际化(i18n)支持**: - 提供了更好的国际化支持,使得应用程序能够根据用户设置的语言...
- **快速入门**:介绍如何设置Spring环境,创建第一个Spring项目,并解释了基本的配置文件结构。 - **IoC容器**:深入解析IoC容器的工作原理,包括Bean的定义、实例化、初始化和销毁,以及Bean之间的依赖关系。 - ...
在搭建Spring的运行环境中,我们需要创建一个新的项目,建立Spring的配置文件,引入必要的Spring库,并编写测试代码来验证配置是否正确。同时,接口的使用至关重要,因为它使得服务的提供者和消费者之间解耦。 在第...
"spring2.5"这个压缩包子文件的名称暗示了源码的主要部分可能与Spring框架有关,可能包含Spring配置文件(如 applicationContext.xml)、DAO和Service层的Java类,以及与Hibernate相关的配置文件(如 hibernate.cfg....
- 设置Spring库并创建第一个Spring应用,包括编写XML配置文件。 - 测试配置环境,确保Spring可以正确初始化和管理Bean。 3. **Spring管理Bean的原理** - 解释Bean的实例化过程,包括单例(Singleton)和原型...
Spring2.5版本是其发展的一个重要里程碑,引入了许多改进和新特性,使得开发者能够更加方便地进行依赖注入、事务管理、AOP(面向切面编程)等关键功能的实现。 在Spring框架中,依赖注入(Dependency Injection,...