首先来看下官方文档上给出的两个例子:
第一个:
<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"/>顺利运行。
运行截图: