我们之前要创建对象时,都需要new
一下,但使用了Spring后,就不需要再new
了,可以直接使用类名调用了。这是因为Spring 已经为我们自动创建好了Java对象(但需要在xml文件里进行一些配置)。
举个例子看看吧:
一个bean就代表一个Java对象 ↑
public class Test {
public static void main(String[] args) {
/*之前需要创建一个date对象,需要自己new 一下*/
Date date = new Date();
System.out.println(date);
/*但现在spring帮我们自动创建*/
ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("application.xml");
/*如果<bean></bean>里没有用到id或name,则这样调用对象*/
Date date = applicationContext.getBean(Date.class);
/*如果<bean></bean>里用到id,则这样调用对象*/
date = applicationContext.getBean(date);
/*如果<bean></bean>里用到name(且有多个值时),则这样调用对象*/
date = applicationContext.getBean(date);
/*或者*/
date = applicationContext.getBean(date2);
System.out.println(date);
applicationContext.close();//释放资源
}
}
同时我们需要知道:
默认情况下,new ClassPathXmlApplicationContext("application.xml")
执行后,spring会自动调用类中的无参构造方法;
lazy-init="true"
很懒,不会随着new ClassPathXmlApplicationContext("application.xml")
的执行而创建对象,而是什么时候获取该对象,什么时候创建。
默认情况下,new ClassPathXmlApplicationContext("application.xml")
执行后,结果为:
即调用了无参构造方法!
但如果在<bean></bean>里添加lazy-init="true"
,即<bean></bean>变为:<bean class="com.jd.vo.Student" lazy-init="true"></bean>
,则只有调用该对象时,才创建对象,并调用无参构造方法。
那当构造方法中有参数,却又想调用构造方法,该怎么办呢?
1、构造方法中参数为基本数据类型或String类型:
public Student(int age,String name){
System.out.println("student "+age+","+name);
}
解决方法:<bean></bean>里用value属性赋值即可
<bean id="student" class="com.jd.vo.Student">
<constructor-arg value="12"></constructor-arg>
<constructor-arg value="Jim"></constructor-arg>
</bean>
结果为:
student 12,Jim
2、构造方法中参数为类类型时:
public Student(Date date){
System.out.println("student "+date);
}
解决方法::<bean></bean>里需要用到 ref 属性
<bean id="student" class="com.jd.vo.Student">
<!--ref用已存在的值-->
<constructor-arg ref="date2"></constructor-arg>
</bean>
结果为:
student Sun Oct 25 00:31:21 GMT+08:00 2020
3、构造方法中参数为List类型时:
public Student(List<String> names){
for (String name:names) { //遍历 list
System.out.println(name);
}
}
解决方法:<bean></bean>里需要用到 list 标签
<bean id="n" class="java.lang.String">
<constructor-arg value="Jimmy"></constructor-arg>
</bean>
<bean class="com.jd.vo.Student">
<constructor-arg>
<list><!--需要list标签-->
<!--然后list里是String类型的数据-->
<value>Tom</value> <!--则可以直接用value属性赋值-->
<bean class="java.lang.String"><!--还可以把String当作一个类,使用bean-->
<constructor-arg value="Lucy"></constructor-arg>
</bean>
<ref bean="n"></ref><!--那就同样可以使用ref属性了-->
</list>
</constructor-arg>
</bean>
结果是:
Tom
Lucy
Jimmy
4、构造方法中参数为数组(array)时:
public Student(int [] scores){
for (int score:scores) {
System.out.println(score);
}
}
解决方法:<bean></bean>里需要用到 array 标签
<bean id="score" class="java.lang.Integer">
<constructor-arg value="600"></constructor-arg>
</bean>
<bean class="com.jd.vo.Student">
<constructor-arg>
<array><!--需要用到array标签-->
<!--array里是int类型的数据-->
<value>606</value><!--所以可以用value属性赋值-->
<bean class="java.lang.Integer"><!--也可以把它看成一个类,使用bean-->
<constructor-arg value="604"></constructor-arg>
</bean>
<ref bean="score"></ref><!--既然是类,那同样可以使用 ref属性-->
</array>
</constructor-arg>
</bean>
结果:
606
604
600
5、构造方法中参数为Set集合时:
public Student(Set<String> addresses){
for (String address:addresses){
System.out.println(address);
}
}
解决方法:<bean></bean>里需要用到 set 标签
<bean id="address" class="java.lang.String">
<constructor-arg value="深圳市"></constructor-arg>
</bean>
<bean class="com.jd.vo.Student">
<constructor-arg>
<set><!--需要用到set标签-->
<!--set里是String类型的数据-->
<value>郑州市</value>
<bean class="java.lang.String">
<constructor-arg value="北京市"></constructor-arg>
</bean>
<ref bean="address"></ref>
</set>
</constructor-arg>
</bean>
结果为:
郑州市
北京市
深圳市
6、构造方法中参数为map集合时:
public Student(Map<String,String> map){
for (String key: map.keySet()){ //map集合里是set集合,遍历set集合
System.out.println("key="+key+",value="+map.get(key));
}
}
解决方法:<bean></bean>里需要用到 map 标签
<bean id="k" class="java.lang.String">
<constructor-arg value="lihua"></constructor-arg>
</bean>
<bean id="v" class="java.lang.String">
<constructor-arg value="广东省深圳市"></constructor-arg>
</bean>
<bean class="com.jd.vo.Student">
<constructor-arg>
<map><!--需要用到map标签-->
<!--map标签里是entry-->
<entry key="Jimmy" value="河南省郑州市"></entry>
<entry key-ref="k" value-ref="v"></entry>
</map>
</constructor-arg>
</bean>
结果为:
key=Jimmy,value=河南省郑州市
key=lihua,value=广东省深圳市
7、构造方法中参数为Properties时(也是key=value形式):
public Student(Properties properties){
System.out.println(properties.getProperty("name"));
System.out.println(properties.getProperty("mobile"));
}
解决方法:<bean></bean>里需要用到 props 标签
<bean class="com.jd.vo.Student">
<constructor-arg>
<props>
<prop key="name">lUCY</prop>
<prop key="mobile">110</prop>
</props>
</constructor-arg>
</bean>
结果为:
LUCY
110
那给setter方法如何赋值呢:
给setter方法赋值:
<!--为setter方法赋值:用property;上面是给构造方法赋值,所以用constructor-arg-->
<bean id="score" class="java.lang.Integer">
<constructor-arg value="97"></constructor-arg>
</bean>
<bean id="name" class="java.lang.String">
<constructor-arg value="Lucy"></constructor-arg>
</bean>
<bean class="com.jd.vo.Student">
<!--给name赋值(String类型)-->
<property name="name" value="Tom"></property>
<!--给scores赋值(数组)-->
<property name="scores" >
<array>
<value>99</value>
<bean class="java.lang.Integer">
<constructor-arg value="98"></constructor-arg>
</bean>
<ref bean="score"></ref>
</array>
</property>
<!--给list赋值(list集合)-->
<property name="list">
<list>
<value>Tom</value>
<bean class="java.lang.String">
<constructor-arg value="Lucy"></constructor-arg>
</bean>
<ref bean="name"></ref>
</list>
</property>
</bean>
说白了,给setter方法赋值除了把<constructor-arg></constructor-arg>
换成<property></property>
,其他的和给有参构造方法的参数赋值如出一辙。
其实,给setter方法赋值除了上面的方法,还有一个更简便的方法:
<!--为setter方法赋值的简便表示方法-->
<!--util里只有set、list、map、properties,没有array(只能用上面的property)-->
<util:list id="li">
<value>80</value>
<value>90</value>
</util:list>
<bean class="com.jd.vo.Student" p:name="Jimmy" p:list-ref="li"></bean>
注意:上面的<util></util>
里只有set、list、map、properties等,没有array,也就是说给数组(array)赋值只能用上面的那一种方法。