Spring学习(三)Spring容器是如何创建对象的

默认情况下是使用类的无参构造器创建的

我们继续创建一个工程。

实体类User.java

package com.hj.pojo;
public class User {
    private String name;

    public User(){
        System.out.println("User无参构造");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("name="+name);
    }
}

然后同时配置beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    
    <bean id="user" class="com.hj.pojo.User">
        <property name="name" value="Spring"/>
    </bean>

</beans>

然后直接在测试类里测试:

import com.hj.pojo.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MyTest {
    public static void main(String[] args) {
        //获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //我们的对象现在都在spring中管理了,我们要使用,直接去取出来就可以了
        //这个时候就已经走了无参构造方法了,说明对象已经被创建了
        //说明对象在context的时候就已经被创建了
        User bean = (User)context.getBean("user");
        bean.show();

    }
}

我们在User bean = (User)context.getBean(“user”);打断点可以查看到context里的内容,可以发现其实User类的对象在context里就已经有了,说明对象的创建在new ClassPathXmlApplicationContext("beans.xml");这句上。

在这里插入图片描述

然后这次我们再把User.java中的无参构造注释掉,改成有参构造,其实在IDEA里就能看到很明显的区别了:

在这里插入图片描述

左边有个豆子并且豆子右下角有个m,点一下可以跳转到我们的beans.xml里。说明spring是走的无参构造。但是我们还是实验一下,把无参构造注释掉:

package com.hj.pojo;
public class User {
    private String name;

//    public User(){
//        System.out.println("User无参构造");
//    }
    public User(String name){
        this.name=name;
        System.out.println("User有参构造");
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public void show(){
        System.out.println("name="+name);
    }
}

继续运行刚刚的测试类,发现直接报错:Caused by: java.lang.NoSuchMethodException: com.hj.pojo.User.<init>()说创建失败,我们没有User类的构造方法。

那spring就没办法使用有参构造来使用了吗?这样会不会太不灵活了?spring有别的办法来做有参构造初始化。

spring使用有参构造器创建对象

打开spring的官方文档:https://www.docs4dev.com/amp/docs/zh/spring-framework/5.1.3.RELEASE/reference/core.html#beans,可以看到在依赖的这章节里,有对依赖注入详细解释。

在这里插入图片描述

我们在基于构造函数的依赖注入这一小节里可以找到如下的解释:

在这里插入图片描述

那么答案就很明显了,我们可以通过<constructor-arg>标签来让其使用有参构造器。

此时我们修改beans.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd">
    <bean id="user" class="com.hj.pojo.User">
        <!--构造函数参数索引-->
        <constructor-arg index="0" value="Spring"/>
    </bean>
    <bean id="user2" class="com.hj.pojo.User">
        <!--构造函数参数类型匹配-->
        <constructor-arg type="java.lang.String" value="Spring"/>
    </bean>
    <bean id="user3" class="com.hj.pojo.User">
        <!--构造函数参数名称 name="参数名称"-->
        <constructor-arg name="name" value="Spring"/>
    </bean>
</beans>

然后再运行测试类,发现不再报错了!而且调用的是有参的构造器!

public class MyTest {
    public static void main(String[] args) {
        //获取spring的上下文对象
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //我们的对象现在都在spring中管理了,我们要使用,直接去取出来就可以了
        //这个时候就已经走了无参构造方法了,说明对象已经被创建了
        //说明对象在context的时候就已经被创建了
        User bean = (User)context.getBean("user");
        bean.show();
        User bean2 = (User)context.getBean("user2");
        bean2.show();
        User bean3 = (User)context.getBean("user3");
        bean2.show();
        //User有参构造
        //User有参构造
        //User有参构造
        //name=Spring
        //name=Spring
        //name=Spring
    }
}

总结

1.默认使用无参构造创建对象

2.如果需要用有参构造,就必须用别的方式:

​ 2.1 索引赋值

<bean id="user" class="com.hj.pojo.User">
    <!--构造函数参数索引-->
    <constructor-arg index="0" value="Spring"/>
</bean>
 2.2 类型赋值
<bean id="user" class="com.hj.pojo.User">
    <!--构造函数参数类型匹配-->
    <constructor-arg type="java.lang.String" value="Spring"/>
</bean>
 2.3 参数名称赋值
<bean id="user3" class="com.hj.pojo.User">
    <!--构造函数参数名称 name="参数名称"-->
    <constructor-arg name="name" value="Spring"/>
</bean>

​ 2.4 引用另外的bean(官方文档的例子)

<beans>
    <bean id="thingOne" class="x.y.ThingOne">
        <constructor-arg ref="thingTwo"/>
        <constructor-arg ref="thingThree"/>
    </bean>
    <bean id="thingTwo" class="x.y.ThingTwo"/>
    <bean id="thingThree" class="x.y.ThingThree"/>
</beans>

3.在配置文件加载的时候,spring容器里面管理的对象就已经初始化了。相当于婚介网站,你注册时候就已经会在那里了,哪怕你不用,他都已经创建好了对象。

本章节代码

本章节代码 中的spring-03中

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值