阅读670 返回首页    go 阿里云 go 技术社区[云栖]


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

本节书摘来自异步社区《Spring攻略(第2版)》一书中的第1章,第1.5节,作者: 【美】Gary Mak , Josh Long , Daniel Rubio着,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.5 指定Bean引用

1.5.1 问题
组成应用程序的Bean往往需要互相协作完成应用功能。为了Bean之间的相互访问,你必须在Bean配置文件中指定Bean引用。

1.5.2 解决方案
在Bean配置文件中,你可以用元素为Bean属性或者构造程序参数指定Bean引用。只需要用元素指定一个简单值就可以轻松完成这一工作。你也可以像内部Bean一样直接地在属性或者构造程序中包含一个Bean声明。

1.5.3 工作原理
在你的序列生成器中接受字符串值作为前缀的灵活性不足以满足将来的要求。如果前缀生成可以由某种编程逻辑自定义将会更好。你可以创建PrefixGenerator接口来定义前缀生成操作。

package com.apress.springrecipes.sequence;

public interface PrefixGenerator {

   public String getPrefix();
}

使用特殊的模式格式化当前系统日期是一种前缀生成策略。让我们创建实现PrefixGenerator接口的DatePrefixGenerator类。

package com.apress.springrecipes.sequence;
...
public class DatePrefixGenerator implements PrefixGenerator {
   private DateFormat formatter;

   public void setPattern(String pattern) {
     this.formatter = new SimpleDateFormat(pattern);
   }

   public String getPrefix() {
     return formatter.format(new Date());
   }
}

这个生成器的模式将通过设值方法setPattern()注入,然后用于创建java.text.DateFormat对象格式化日期。由于模式字符串在DateFormat对象创建之后不再使用,所以没有必要将它存入一个私有字段中。

现在你可以用任意模式字符串声明类型为DatePrefixGenerator的Bean来格式化日期。

<bean 
   >
   <property name="pattern" value="yyyyMMdd" />
</bean>

为设值方法指定Bean引用
为了应用这个前缀生成器方法,SequenceGenerator类应该接受PrefixGenerator类型的对象而不是简单的前缀字符串。你可以选择设置方法注入来接受这个前缀生成器。你必须删除可能导致编译错误的prefix属性,以及设值方法和构造程序。

package com.apress.springrecipes.sequence;

public class SequenceGenerator {
   ...
   private PrefixGenerator prefixGenerator;

   public void setPrefixGenerator(PrefixGenerator prefixGenerator) {
     this.prefixGenerator = prefixGenerator;
   }

   public synchronized String getSequence() {
     StringBuffer buffer = new StringBuffer();
     buffer.append(prefixGenerator.getPrefix());
     buffer.append(initial + counter++);
     buffer.append(suffix);
     return buffer.toString();
   }
}

然后,SequenceGenerator bean可以包含一个元素,引用datePrefixGenerator bean作为其prefixGenerator属性。

<bean 
   >
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
   <property name="prefixGenerator">
     <ref bean="datePrefixGenerator" />
   </property>
</bean>

元素的bean属性中的Bean名称可以是对IoC容器中的任何Bean的引用,即使这个Bean不在同一个XML配置文件中定义。如果你引用相同XML文件中的一个Bean,应该使用local属性,因为这是一个XML ID引用。你的XML编辑器将帮助你校验Bean ID是否存在于相同的XML文件中(也就是引用完整性)。

<bean 
   >
   ...
   <property name="prefixGenerator">
     <ref local="datePrefixGenerator" />
   </property>
</bean>

还有一个在元素的ref属性中指定Bean引用的方便简写。

<bean 
   >
   ...
   <property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>

但是这样一来,你的XML编辑器将不能校验引用完整性。实际上,这跟指定元素的bean属性效果相同。

Spring 2.x提供另一个便利的简写来指定Bean引用,使用pschema将bean引用作为元素的一个属性。这可以缩短XML配置行。

<beans xmlns="https://www.springframework.org/schema/beans"
   xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
   xmlns:p="https://www.springframework.org/schema/p"
   xsi:schemaLocation="https://www.springframework.org/schema/beans
     https://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

   <bean 
     
     p:suffix="A" p:initial="1000000"
     p:prefixGenerator-ref="datePrefixGenerator" />
</beans>

为了区分Bean引用与简单的属性值,你必须在属性名后面加上-ref后缀。

为构造程序参数指定Bean引用
Bean引用也可以应用到构造程序注入。例如,你可以添加一个接受PrefixGenerator对象参数的构造程序。

package com.apress.springrecipes.sequence;

public class SequenceGenerator {
   ...
   private PrefixGenerator prefixGenerator;

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

在元素中,你可以用像在元素中一样包含一个Bean引用。

<bean 
   >
   <constructor-arg>
     <ref local="datePrefixGenerator" />
   </constructor-arg>
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
</bean>

指定Bean引用的简写也适用于。

<bean 
   >
   <constructor-arg ref="datePrefixGenerator" />
   ...
</bean>

声明内部Bean
如果Bean实例只用于一个特殊的属性,可以声明为内部Bean。内部Bean声明直接包含在或中,不设置任何id或者name属性。这样,这个Bean将是匿名的,无法在别处使用。实际上,即使为内部Bean定义id或者name属性,也将被忽略。

<bean 
   >
   <property name="initial" value="100000" />
   <property name="suffix" value="A" /
   <property name="prefixGenerator">
     <bean >
        <property name="pattern" value="yyyyMMdd" />
     </bean>
   </property>
</bean>

内部Bean也可以在构造程序参数中声明。

<bean 
   >
   <constructor-arg>
     <bean >
        <property name="pattern" value="yyyyMMdd" />
     </bean>
   </constructor-arg>
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
</bean>

最后更新:2017-05-31 15:01:40

  上一篇:go  《Spring攻略(第2版)》——1.6 为集合元素指定数据类型
  下一篇:go  《Spring攻略(第2版)》——1.4 解决构造程序歧义