我们之前要创建对象时,都需要new一下,但使用了Spring后,就不需要再new了,可以直接使用类名调用了。这是因为Spring 已经为我们自动创建好了Java对象(但需要在xml文件里进行一些配置)。

       举个例子看看吧:

spring如何注解有参构造器_spring


一个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")的执行而创建对象,而是什么时候获取该对象,什么时候创建。

spring如何注解有参构造器_xml_02


spring如何注解有参构造器_spring如何注解有参构造器_03


默认情况下,new ClassPathXmlApplicationContext("application.xml")执行后,结果为:

spring如何注解有参构造器_xml_04


即调用了无参构造方法!

但如果在<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方法如何赋值呢:

spring如何注解有参构造器_xml_05


给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)赋值只能用上面的那一种方法。