《Spring攻略(第2版)》——1.11 用XML配置自动装配Bean

1.11 用XML配置自动装配Bean

1.11.1 问题
当一个Bean需要访问另一个Bean时,你可以显式指定引用装配它。但是,如果你的容器能够自动装配Bean,就可以免去手工配置装配的麻烦。

1.11.2 解决方案
Spring IoC容器能够帮助你自动装配Bean。你只要在的autowire属性中指定自动装配模式就可以了。表1-2列出了Spring支持的自动装配模式。

*默认模式是no,但是可以设置根元素的default-autowire属性修改。这个默认模式将被Bean自己指定的模式覆盖。

尽管自动装配功能非常强大,但代价是降低了Bean配置的可读性。因为自动装配由Spring在运行时执行,你无法从Bean配置文件中得到Bean装配的方式。在实践中,我们建议仅将自动装配应用到组件依赖不复杂的应用程序中。

1.11.3 工作原理
按照类型的自动装配
你可以将sequenceGenerator bean的autowire属性设置为byType并且不设置prefixGenerator属性。然后,Spring将试图装配类型与PrefixGenerator兼容的Bean。在这个例子中,将自动装配datePrefixGenerator bean。

<beans ...>
   <bean id="sequenceGenerator"
     class="com.apress.springrecipes.sequence.SequenceGenerator"
     autowire="byType">
     <property name="initial" value="100000" />
     <property name="suffix" value="A" />
   </bean>

   <bean id="datePrefixGenerator"
     class="com.apress.springrecipes.sequence.DatePrefixGenerator">
     <property name="pattern" value="yyyyMMdd" />
   </bean>
</beans>

按照类型的自动装配的主要问题是有时候在IoC类型中具有超过一个与目标类型兼容的Bean。在这种情况下,Spring将无法确定哪个Bean最适合于该属性,从而无法进行自动装配。例如,如果你有另一个以当前年份作为前缀的前缀生成器,按照类型的自动装配将会立即被破坏。

<beans ...>
   <bean id="sequenceGenerator"
     class="com.apress.springrecipes.sequence.SequenceGenerator"
     autowire="byType">
     <property name="initial" value="100000" />
     <property name="suffix" value="A" />
   </bean>

   <bean id="datePrefixGenerator"
     class="com.apress.springrecipes.sequence.DatePrefixGenerator">
     <property name="pattern" value="yyyyMMdd" />
   </bean>

   <bean id="yearPrefixGenerator"
     class="com.apress.springrecipes.sequence.DatePrefixGenerator">
     <property name="pattern" value="yyyy" />
   </bean>
</beans>

如果找到超过一个可供自动装配的Bean,Spring将会抛出一个UnsatisfiedDependency Exception异常。

Exception in thread "main"
org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'sequenceGenerator' defined in class path resource [beans.xml]: Unsatisfied dependency expressed through bean property 'prefixGenerator': No unique bean of type [com.apress.springrecipes.sequence.PrefixGenerator] is defined: expected single matching bean but found 2: [datePrefixGenerator, yearPrefixGenerator]

按照名称的自动装配
byName是另一种自动装配模式,有时候它能解决按照类型的自动装配的问题。它的工作方式与byType类似,但是这时候,Spring将试图装配一个类名与该属性名相同的Bean,而不是兼容的类型。因为Bean的name属性在一个容器中是唯一的,按照名称的自动装配不会导致歧义。

<beans ...>
   <bean id="sequenceGenerator"
     class="com.apress.springrecipes.sequence.SequenceGenerator"
     autowire="byName">
     <property name="initial" value="100000" />
     <property name="suffix" value="A" />
   </bean>

   <bean id="prefixGenerator"
     class="com.apress.springrecipes.sequence.DatePrefixGenerator">
     <property name="pattern" value="yyyyMMdd" />
   </bean>
</beans>

但是,按照名称的自动装配并不能工作于任何情况。有时候,你不可能使目标Bean的名称与属性相同。在实践中,你往往必须在保持其他依赖自动装配的同时明确地指定歧义的依赖。这意味着你混合了显式装配和自动装配。

按照构造程序的自动装配
constructor自动装配模式与byType的工作方式类似,但是更复杂一些。对于具有单个构造程序的Bean,Spring将试图为每个构造程序参数装配一个具有兼容类型的Bean。但是对于具有多个构造程序的Bean,这一过程就更加复杂。Spring首先试图为每个构造程序的每个参数找到一个类型兼容的Bean。然后,将选择具有最多匹配参数的构造程序。

假定SequenceGenerator有一个默认构造程序和一个具有参数PrefixGenerator的构造程序。

package com.apress.springenterpriserecipes.sequence;

public class SequenceGenerator {

   public SequenceGenerator() {}

   public SequenceGenerator(PrefixGenerator prefixGenerator) {
     this.prefixGenerator = prefixGenerator;
   }
   ...
}

在这种情况下,第二个构造程序匹配并且被选中,因为Spring可以找到一个类型与Prefix Generator兼容的Bean。

<beans ...>
   <bean id="sequenceGenerator"
     class="com.apress.springrecipes.sequence.SequenceGenerator"
     autowire="constructor">
     <property name="initial" value="100000" />
     <property name="suffix" value="A" />
   </bean>

   <bean id="datePrefixGenerator"
     class="com.apress.springrecipes.sequence.DatePrefixGenerator">
     <property name="pattern" value="yyyyMMdd" />
   </bean>
</beans>

但是,一个类中的多个构造程序可能造成构造程序参数匹配的歧义。如果你要求Spring确定一个构造程序,情况可能更加复杂。所以,如果你使用这种自动装配模型,就要非常小心地避免歧义。

自动检测的自动装配
自动装配模式autodetect要求Spring在byType和constructor模式中作出决定。如果至少找到一个没有参数的默认构造程序,将选择byType模式,否则,将选择constructor模式。因为SequenceGenerator类定义了默认的构造程序,将选择byType模式。这意味着前缀生成器将通过设值方法注入。

<beans ...>
   <bean id="sequenceGenerator"
     class="com.apress.springrecipes.sequence.SequenceGenerator"
     autowire="autodetect">
     <property name="initial" value="100000" />
     <property name="suffix" value="A" />
   </bean>

   <bean id="datePrefixGenerator"
     class="com.apress.springrecipes.sequence.DatePrefixGenerator">
     <property name="pattern" value="yyyyMMdd" />
   </bean>
</beans>

自动装配与依赖检查
你已经看到,如果Spring找到超过一个候选的自动装配Bean,将会抛出UnsatisfiedDependency Exception异常。另一方面,如果自动装配模式设置为byName或byType,而Spring无法找到匹配的Bean进行装配,将把该属性保持为未设置状态,这可能导致一个NullPointerException异常或者一个值没有初始化。但是,如果你希望在自动装配无法装配的Bean时得到通知,应该将dependency-check属性设置为objects或者all。

在这种情况下,如果自动装配无效将会抛出UnsatisfiedDependencyException异常。objects将通知Spring在相同的Bean工厂中无法找到协同Bean时发出一个错误。all通知容器在任何作为依赖的简单属性类型(String类型或者原始类型)未被设置时发出一个错误,这补充了objects的功能。

<bean id="sequenceGenerator"
   class="com.apress.springrecipes.sequence.SequenceGenerator"
   autowire="byName" dependency-check="objects">
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
</bean>
时间: 2024-08-31 15:14:40

《Spring攻略(第2版)》——1.11 用XML配置自动装配Bean的相关文章

《Spring实战(第4版)》——2.2 自动化装配bean

2.2 自动化装配bean 在本章稍后的内容中,你会看到如何借助Java和XML来进行Spring装配.尽管你会发现这些显式装配技术非常有用,但是在便利性方面,最强大的还是Spring的自动化配置.如果Spring能够进行自动化装配的话,那何苦还要显式地将这些bean装配在一起呢? Spring从两个角度来实现自动化装配: 组件扫描(component scanning):Spring会自动发现应用上下文中所创建的bean.自动装配(autowiring):Spring自动满足bean之间的依赖

《Spring攻略(第2版)》——导读

前言 Spring框架正在成长.它始终与选择相关.Java EE关注于少数几项技术,很大程度上阻碍了更好的替代解决方案出现.当Spring框架出现时,没有多少人还会承认Java EE是当今最佳的架构. 随后Spring被大张旗鼓地推出,因为它寻求简化Java EE.此后其每个版本都引入设计用来简化和实现解决方案的新特性. 从2.0版本之后,Spring框架开始针对多平台.和往常一样,该框架提供了现有平台之上的服务,但是尽可能去除与底层平台的耦合.Java EE仍然是主要的参考点,但是不是唯一的目

《Spring攻略(第2版)》——1.12 用@Autowired和@Resource自动装配Bean

1.12 用@Autowired和@Resource自动装配Bean 1.12.1 问题 在Bean配置文件中设置autowire属性进行的自动装配将装配一个Bean的所有属性.这样的灵活性不足以仅仅装配特定的属性.而且,你只能通过类型或者名称自动装配Bean.如果这两种策略都不能满足你的需求,就必须明确地装配Bean. 1.12.2 解决方案 从Spring 2.5起,自动装配功能进行了多处改进.你可以通过用@Autowired或者@Resource(在JSR-250:Java平台常见注解中定

《Spring攻略(第2版)》——1.15 小结

1.15 小结 在本章中,你已经学习了Spring IoC容器中的基本Bean配置.Spring支持多种Bean配置.在这些配置中,XML是最简单和最自然的.Spring提供两种IoC容器实现.基本的实现是Bean工厂,高级的实现是应用程序上下文.如果可能,你应该使用应用程序上下文,除非资源有限.Spring支持用Setter注入和构造程序注入定义Bean属性,属性可以是简单值.集合或者Bean引用. 依赖检查和自动装配是Spring提供的两种有价值的容器特性.依赖检查帮助检查所有必要的属性是否

阿里妈妈联盟申请注册攻略(站长版)

中介交易 SEO诊断 淘宝客 云主机 技术大厅 阿里妈妈注册攻略(站长版) 阿里妈妈面世已经快一个月了,有很多朋友对于阿里妈妈的注册以及发布广告位流程不是很清楚.特别是作为 卖家,对于发布广告位之类的操作了解不多,特发布注册秘笈,以帮助大家更好的理解阿里妈妈的运作流程. 整体来说,要想成功在阿里妈妈注册,需要完成三个步骤: 一.注册成为阿里妈妈的会员 二.登记网站并发布广告位 三.投放广告代码 注意:上面这三个步骤主要是针对卖家在阿里妈妈出售广告位. 话不多说,开始注册了! 第一部分 注册成为阿

《Spring攻略(第2版)》——1.13 继承Bean配置

1.13 继承Bean配置 1.13.1 问题在Spring IoC容器中配置Bean时,你可能拥有超过一个共享某些公用配置的Bean,比如属性和元素中的属性.你常常必须为多个Bean重复这些配置. 1.13.2 解决方案Spring允许你提取公用的Bean配置组成一个父Bean.从父Bean继承而来的Bean称作子Bean.子Bean从父Bean继承Bean配置,包括Bean属性和元素中的属性,避免重复配置.子Bean在必要时也可以覆盖继承的配置. 父Bean可以作为配置模板,也可以同时作为B

《Spring攻略(第2版)》——1.2 配置Spring IoC容器中的Bean

1.2 配置Spring IoC容器中的Bean 1.2.1 问题 Spring提供了一个强大的IoC容器来管理组成应用的bean.为了利用容器服务,你必须配置运行于Spring IoC容器中的Bean. 1.2.2 解决方案 你可以通过XML文件.属性文件.注释甚至API来配置Spring IoC容器中的Bean. Spring允许你在一个或者多个bean配置文件中配置bean.对于简单的应用程序,可以在单个配置文件中集中配置bean.但是对于有许多bean的大型应用,你应该根据其功能(例如控

《Spring攻略(第2版)》——1.5 指定Bean引用

1.5 指定Bean引用 1.5.1 问题 组成应用程序的Bean往往需要互相协作完成应用功能.为了Bean之间的相互访问,你必须在Bean配置文件中指定Bean引用. 1.5.2 解决方案 在Bean配置文件中,你可以用元素为Bean属性或者构造程序参数指定Bean引用.只需要用元素指定一个简单值就可以轻松完成这一工作.你也可以像内部Bean一样直接地在属性或者构造程序中包含一个Bean声明. 1.5.3 工作原理 在你的序列生成器中接受字符串值作为前缀的灵活性不足以满足将来的要求.如果前缀生

《Spring攻略(第2版)》——第1章 Spring简介 1.1实例化Spring IoC容器

第1章 Spring简介 在本章中,你将参加关于Spring.核心容器以及容器所提供的一些全局可用设施的一个速成班(或者一次复习),你还将了解Spring XML配置格式,以及注释驱动的支持.本章将带给你应付本书余下部分中引入的概念所需要的知识.你将学习Spring IoC容器中的基本组件配置.在Spring框架的核心部分,IoC容器的设计具有高度的适应性和可配置性,提供了使你的组件配置尽可能简单的一组工具.你能够很简单地设置运行于Spring IoC容器中的组件. 在Spring中,组件也被称