使用spring框架时就可以很少再创建对象了。spring框架可以根据bean标签中class标签属性的值自动创建对象。那么spring框架是怎样调用构造方法的呢?
首先搭建这样的Java项目结构
Test类里的代码(固定不变)
package com.test;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.vo.Person;
public class Test {
public static void main(String[] args) {
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("app.xml");
System.out.println(applicationContext.getBean(Person.class));//验证对象是否为空
}
}
调用无参构造方法的情况
Person中的代码
package com.vo;
public class Person {
private String name;
public Person() {
System.out.println("无参构造方法");
}
public Person(String name) {
this.name = name;
System.out.println(this.name);
}
}
app.xml中的代码(以后的代码只展示beans中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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.2.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.3.xsd">
<bean class="com.vo.Person"></bean>
</beans>
此时运行Test类,结果如下图
可见当bean标签只指定了要创建的类时,bean双标签中没有任何配置时,默认调用无参构造方法。
调用有参构造方法时(此时情况比较复杂分几个种类讨论)
1、参数为基本数据类型(及其包装类)和String类型时
Person中的代码
package com.vo;
public class Person {
private String name;
public Person(String name) {
this.name = name;
System.out.println(this.name);
}
app.xml中的代码
<bean class="com.vo.Person">
<constructor-arg name="name" value="string类型"></constructor-arg>
</bean>
此时配置了constructor-arg标签即配置创建的对象的属性,也就是给构造方法传参,并根据参数列表的数据类型指定使用哪个构造方法创建对象。其中name标签属性就是指定类中被赋值属性的名字,value就是给属性赋值。
运行结果如下
可将String类型换为任意的基本数据类型(及其包装类),得出来的实验结果是相似的。
2、为其他引用数据类型(数组,集合单独讨论)时
需要再在beans标签内创建一个新的引用类型对象 并在 constructor-arg 标签中用ref标签属性配置指定的引用类型对象。
Person中的代码
package com.vo;
import java.util.Date;
public class Person {
private Date date;
public Person(Date date) {
this.date = date;
System.out.println(this.date);
}
}
app.xml中的代码
<bean class="java.util.Date" id="date"></bean>
<bean class="com.vo.Person">
<constructor-arg ref="date"></constructor-arg>
</bean>
最上面的id标签属性等于是给新创建的Date类对象一个名字, constructor-arg 标签中的ref值就是指定使用哪个配置了id标签属性的类。
运行结果如下
3、为数组时
Person中的代码
package com.vo;
public class Person {
private double [] moneys;
public Person(double [] moneys) {
this.moneys = moneys;
for (double d : this.moneys) {
System.out.println(d);
}
}
}
app.xml中的代码
<bean class="com.vo.Person">
<constructor-arg name="moneys">
<array>
<value>100</value>
<value>199</value>
<value>90</value>
</array>
</constructor-arg>
</bean>
此时在constructor-arg 标签内部配置array标签,此时可以在array标签内配置一系列value标签也就是数组各个元素的值。
运行结果如下
4、为集合(set list)(数据类型为:数据类型包装类、String类型)时
Person中的代码
package com.vo;
import java.util.List;
public class Person {
private List<String> list;
public Person(List<String> list) {
this.list = list;
for (String s : this.list) {
System.out.println(s);
}
}
}
app.xml中的代码
<bean class="com.vo.Person">
<constructor-arg name="list">
<list>
<value>dasd</value>
<value>sdasd</value>
<value>sdas</value>
</list>
</constructor-arg>
</bean>
此时在constructor-arg 标签内部配置list(set)标签,此时可以在list(set)标签内配置一系列value标签也就是数组各个元素的值。
5、为集合(map)时
Person中的代码
package com.vo;
import java.util.Map;
import java.util.Set;
public class Person {
private Map<String, Object> map;
public Person(Map<String, Object> map) {
this.map = map;
Set<String> set = map.keySet();
for (String s : set) {
System.out.println(map.get(s));
}
}
}
app.xml中的代码
<bean class="java.util.Date" id="date"></bean>
<bean class="com.vo.Person">
<constructor-arg name="map">
<map>
<entry key="dad" value="11"></entry>
<entry key="day" value-ref="date"></entry>
</map>
</constructor-arg>
</bean>
此时在constructor-arg 标签内部配置map标签,此时可以在map标签内配置一系列entry标签也就是数组各个元素的值。
entry标签内key就是map中元素的key值,value就是map中元素的value值。
value-ref 跟上面的ref属性是一样的,就是指向一个非数据类型包装类及string类型的引用数据类型。
同样的也有key-ref 作用相似。
6、为集合(set list)(数据类型为:除了数据类型包装类、String类型)时
Person中的代码
package com.vo;
import java.util.Date;
import java.util.Set;
public class Person {
private Set<Date> dates;
public Person(Set<Date> dates) {
this.dates = dates;
for (Date date : this.dates) {
System.out.println(date);
}
}
}
app.xml中的代码
<bean class="java.util.Date" id="date"></bean>
<bean class="com.vo.Person">
<constructor-arg name="dates">
<set>
<ref bean="date"/>
<bean class="java.util.Date"></bean>
</set>
</constructor-arg>
</bean>
此中ref单标签是为了引用其所属bean标签之外的bean标签创建的对象,bean属性跟上面介绍ref属性是类似的。
set标签中bean是创建一个新的对象。
运行结果如下