Spring攻略学习笔记(5)指定Bean引用

        组成应用程序的Bean往往旭阳互相协作完成应用功能。为了Bean之间的相互访问,你必须在Bean配置文件中指定Bean引用,可以使用<ref>元素为Bean属性或者构造程序参数指定Bean引用可以像内部Bean一样,直接在属性或者构造程序中包含一个Bean声明。

       (1)PrefixGenerator接口

/*
 * Copyright 2013-2015
 */
package com.jackie.codeproject.springrecipesnote.springioc;

/**
 * Title: PrefixGenerator.java 
 * 生成前缀
 * 
 * @author jackie
 * @since Apr 18, 2013 9:54:43 PM
 * @version V1.0
 */
public interface PrefixGenerator {
    public String getPrefix();
}

  (2)日期前缀生成器DatePrefixGenerator

/*  
  * Copyright 2013-2015  
  */
package com.jackie.codeproject.springrecipesnote.springioc;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Title: DatePrefixGenerator.java
 *  日期前缀
 * 
 * @author jackie
 * @since Apr 18, 2013 10:03:02 PM
 * @version V1.0
 */
public class DatePrefixGenerator implements PrefixGenerator {
     private DateFormat formatter;
     
     public void setPattern(String pattern) {
        this.formatter = new SimpleDateFormat(pattern);
    }

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

(3)序列生成器SequenceGenerator

/*
 * Copyright 2013-2015
 */
package com.jackie.codeproject.springrecipesnote.springioc;

/**
 * Title: SequenceGenerator.java 
 * 序列生成器
 * 
 * @author jackie
 * @since Apr 13, 2013 12:56:57 PM
 * @version V1.0
 */
public class SequenceGenerator {

    /**
     * @Fields prefixGenerator : 前缀生成器
     */
    private PrefixGenerator prefixGenerator;
   
    /**
     * @Fields suffix : 后缀
     */
    private String suffix;

    /**
     * @Fields initial : 初始值
     */
    private int initial;

    /**
      * @Fields counter : 计数器
      */
    private int counter;
    
    public SequenceGenerator() {
        
    }
    
    public SequenceGenerator(PrefixGenerator prefixGenerator){
        this.prefixGenerator = prefixGenerator;
    }

    /**
      * 获取序列号,声明为同步,使其成为线程安全的方法
      * @author jackie  
      * @date Apr 13, 2013
      * @return    
      * @return String   
      */
    public synchronized String getSquence() {
        StringBuffer buffer = new StringBuffer();
        buffer.append(prefixGenerator.getPrefix());
        buffer.append(initial + counter++);
        buffer.append(suffix);
        return buffer.toString();
    }
   
   /**
    * <p>Title: </p>
    * <p>Description: </p>
    * @param suffix
    * @param initial
    */
  public SequenceGenerator(int initial, String suffix) {
      this.suffix = suffix;
      this.initial = initial;
  }

    /**
     * @param suffix
     *            the suffix to set
     */
    public void setSuffix(String suffix) {
        this.suffix = suffix;
    }

    /**
     * @param initial
     *            the initial to set
     */
    public void setInitial(int initial) {
        this.initial = initial;
    }

    /**
     * @param prefixGenerator the prefixGenerator to set
     */
    public void setPrefixGenerator(PrefixGenerator prefixGenerator) {
        this.prefixGenerator = prefixGenerator;
    }
}

(4)Bean配置文件

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd">
    <bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
        <property name="pattern" value="yyyyMMdd" />
    </bean>

    <bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
        <constructor-arg name="initial" value="100000" />
        <constructor-arg name="suffix" value="A" />
        <property name="prefixGenerator">
            <ref bean="datePrefixGenerator" />
        </property>
    </bean>
</beans>

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

<bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
   <property name="pattern" value="yyyyMMdd" />
</bean>

<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
   <constructor-arg name="initial" value="100000" />
   <constructor-arg name="suffix" value="A" />
   <property name="prefixGenerator">
      <ref local="datePrefixGenerator" />
   </property>
</bean>

也可以在<property>元素的ref属性中指定Bean引用。不过Spring容器不会校验引用完整性

<bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
   <property name="pattern" value="yyyyMMdd" />
</bean>
    
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
   <constructor-arg name="initial" value="100000" />
   <constructor-arg name="suffix" value="A" />
   <property name="prefixGenerator" ref="datePrefixGenerator" />
</bean>


可以使用p schema将bean引用作为<bean>元素的一个属性。

<bean id="datePrefixGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
   <property name="pattern" value="yyyyMMdd" />
</bean>
    
<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator" p:suffix="A" p:initial="100000" p:prefixGenerator-ref="datePrefixGenerator" />

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


Bean引用也可以应用到构造程序注入。

......
private PrefixGenerator prefixGenerator;

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

在<constructor-arg>元素中,可以用<ref>像在<property>元素中一样包含一个Bean引用。

<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
   <constructor-arg>
      <ref local="datePrefixGenerator" />
   </constructor-arg>
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
</bean>


简写形式

<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
   <constructor-arg ref="datePrefixGenerator" />
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
</bean>


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

<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
   <property name="prefixGenerator">
      <bean class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
         <property name="pattern" value="yyyyMMdd" />
      </bean>
   </property> 
</bean>

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

<bean id="sequenceGenerator" class="com.jackie.codeproject.springrecipesnote.springioc.SequenceGenerator">
   <property name="initial" value="100000" />
   <property name="suffix" value="A" />
   <constructor-arg>
      <bean class="com.jackie.codeproject.springrecipesnote.springioc.DatePrefixGenerator">
         <property name="pattern" value="yyyyMMdd" />
      </bean>
   </constructor-arg> 
</bean>


原文地址:https://www.cnblogs.com/xinyuyuanm/p/3030831.html