首先來看下官方文件上給出的兩個例子:
第一個:

<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
    <property name="targetName">
        <idref bean="theTargetBean" />
    </property>
</bean>

第二個:

<bean id="theTargetBean" class="..." />

<bean id="client" class="...">
    <property name="targetName" value="theTargetBean" />
</bean>

官方的說明:The above bean definition snippet is exactly equivalent (at runtime) to the following snippet(大概意思:這兩個片段配置是等價的在執行的時候).從下面的一個例子可以看出來targetName注入的是“theTargetBean”字串。

<bean id="theTargetBean" class="..."/>

<bean id="theClientBean" class="...">
    <property name="targetName">
        <ref bean="theTargetBean" />
    </property>
</bean>

然而如果是ref標籤那麼就是注入”theTargetBean”例項。
那麼idref的作用是什麼?同樣看下官方給出的說明:The idref element is simply an error-proof way to pass the id (string value - not a reference) of another bean in the container to a or element.(通過或者注入bean的時候通過idref來檢查注入的bean是否在容器中的一種檢查錯誤的方式)。

區別:

ref:注入的是bean的例項
idref:注入的是string。

測試案例:
Cat.java

package com.mxsm.spring.bean;

import java.beans.ConstructorProperties;

public class Cat {

    private String name;

    private String age;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAge() {
        return age;
    }

    public void setAge(String age) {
        this.age = age;
    }

    @Override
    public String toString() {
        return "Cat [name=" + name + ", age=" + age + "]";
    }

    /**
     * ConstructorProperties註解用來設定建構函式的引數的名稱
     * @param name
     * @param age
     */
    @ConstructorProperties({"a","b"})
    public Cat(String name, String age) {
        super();
        this.name = name;
        this.age = age;
    }

    public Cat() {
        super();
        // TODO Auto-generated constructor stub
    }

}

JavaTypeBean.java

package com.mxsm.spring.bean;

import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;

public class JavaTypeBean {

    private Properties properties;

    private Properties properties2;

    private List<String> list;

    private Map<String, Object> map;

    private Set<Object> set;


    public Set<Object> getSet() {
        return set;
    }

    public void setSet(Set<Object> set) {
        this.set = set;
    }

    public JavaTypeBean(Properties properties, List<String> list,
            Map<String, Object> map) {
        super();
        this.properties = properties;
        this.list = list;
        this.map = map;
    }

    public JavaTypeBean() {
        super();
        // TODO Auto-generated constructor stub
    }

    public Properties getProperties() {
        return properties;
    }

    public void setProperties(Properties properties) {
        this.properties = properties;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }

    public Map<String, Object> getMap() {
        return map;
    }

    public void setMap(Map<String, Object> map) {
        this.map = map;
    }

    public Properties getProperties2() {
        return properties2;
    }

    public void setProperties2(Properties properties2) {
        this.properties2 = properties2;
    }

}

Spring的配置檔案:

    <bean id="javatype" class="com.mxsm.spring.bean.JavaTypeBean">
        <!-- Properties集合型別注入方式1 -->
        <property name="properties">
            <value>
                jdbc.driverClassName=com.mysql.jdbc.Driver
                jdbc.url=jdbc:mysql://localhost:3306/ssh
                jdbc.username=root
                jdbc.password=sys123
            </value>
        </property>
        <!-- Properties集合型別注入方式2 -->
        <property name="properties2">
            <props>
                <prop key="key1">aaaaaa</prop>
                <prop key="key2">333333</prop>
            </props>
        </property>

        <!-- Map集合注入方式 -->
        <property name="map">
            <map>
                <entry key="string_1" value="is a String" /><!-- value 是字串 -->
                <entry key="object_cat" value-ref="cat"/><!-- value Cat物件 -->

            </map>
        </property>

        <!-- set 集合注入方式 -->
        <property name="set">
            <set>
                <bean id="cat_1" class="com.mxsm.spring.bean.Cat">
                    <constructor-arg name="b" value="1" />
                    <constructor-arg name="a" value="aaa1" />
                </bean>
                <idref bean="cata"/>
                <value>is a set</value>
            </set>
        </property>
    </bean>

    <bean id="cat" class="com.mxsm.spring.bean.Cat">
        <constructor-arg name="b" value="1" />
        <constructor-arg name="a" value="aaa" />
    </bean>

測試程式碼(用了測試框架Junit4):

package com.mxsm.spring;

import static org.junit.Assert.*;

import java.util.Iterator;
import java.util.Set;

import org.junit.Test;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

import com.mxsm.spring.bean.Cat;
import com.mxsm.spring.bean.JavaTypeBean;

public class SpringJavaType {

    /**
     * 
     */
    @Test
    public void springJavaTypeTest(){
        @SuppressWarnings("resource")
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("application_javatype.xml");
        JavaTypeBean types = applicationContext.getBean("javatype",JavaTypeBean.class);

        //測試Properties
        assertEquals("com.mysql.jdbc.Driver", types.getProperties().getProperty("jdbc.driverClassName"));
        System.out.println(types.getProperties().getProperty("jdbc.username"));

        System.out.println(types.getProperties2().getProperty("key1"));

        //測試Map Map<String,Object>
        assertEquals("is a String",types.getMap().get("string_1"));
        assertEquals("1",((Cat)types.getMap().get("object_cat")).getAge());

        //set 測試
        Set<Object> set = types.getSet();

        Iterator<Object> it = set.iterator();

        while(it.hasNext()){
            System.out.println(it.next());
        }

    }

}

執行測試程式碼會有錯誤:

<property name="set">中設定了<idref bean="cata"/> 而cata這個bean在當前的容器中並不存在所以出錯。將<idref bean="cata"/> 改為<idref bean="cat"/>順利執行。

執行截圖:
這裡寫圖片描述