天天看点

Spring idref标签和ref的区别

首先来看下官方文档上给出的两个例子:

第一个:

<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"/>顺利运行。
           

运行截图:

Spring idref标签和ref的区别