Spring基础学习之IOC创建对象的方式

前言

小伙伴们,大家好,我是狂奔の蜗牛rz,当然你们可以叫我蜗牛君,我是一个学习Java半年多时间的小菜鸟,同时还有一个伟大的梦想,那就是有朝一日,成为一个优秀的Java架构师。
这个Spring基础学习系列是用来记录我学习Spring框架基础知识的全过程 (这个系列是参照B站狂神的Spring5最新教程来写的,由于是之前整理的,但当时没有发布出来,所以有些地方可能有错误,希望大家能够及时指正!)
之后我将会以一天一更的速度更新这个系列,还没有学习Spring5框架的小伙伴可以参照我的博客学习一下;当然学习过的小伙伴,也可以顺便跟我一起复习一下基础。
最后,希望能够和大家一同进步吧!加油吧!少年们!
废话不多说,让我们开始今天的学习内容吧,今天我们来到了Spring基础学习的第四站:IOC创建对象的方式!

4.IOC创建对象的方式

4.1 使用无参构造创建对象

概述

构造器实例化:它是指Spring容器通过Bean对应类中的默认的构造函数来实例化Bean

步骤

  • 首先创建一个User实体类对象,定义个name属性,然后生成它的无参构造以及get和set方法
  • 接着编写applicationContext.xml配置文件,注册bean节点,配置两个属性:id和class:id是user对象的唯一标识名,class是User类的全限定名;然后在bean标签中配置property,有name和value两个属性:name是User类的字段名称,value是对应字段的属性值 (相当于key-value)
  • 最后编写测试类,定义配置文件路径,然后通过ApplicationContext加载配置文件,并且实例化Bean对象,调用getBean方法获取Spring容器中的通过无参构造创建的实例化Bean

4.1.1 编写User实体类

package com.kuang.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);
    }
}

4.1.2 编写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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!--默认使用无参构造创建对象-->
    <bean id="user" class="com.kuang.pojo.User">
    	<property name="name" value="罗翔老师"/>   
    </bean>
</beans>

4.1.3 编写MyTest测试类

public class MyTest {
    public static void main(String[] args) {
        //ApplicationContext在加载配置文件时,对Bean进行实例化
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //对象都在Spring容器,要使用直接取出来使用即可
        User user = (User) context.getBean("user");
        //调用show方法显示用户名
        user.show();
    }
}

4.1.4 测试结果

在这里插入图片描述

4.1.5 Debug测试观察Bean的生命周期

1.设置断点
  • 在获取Bean这行代码前设置断点

在这里插入图片描述

2.进行Debug测试
  • 右击主方法,选择Debug‘MyTest.main’

在这里插入图片描述

3.Debug测试结果
3-1 查找lifecycleProcessor
  • Debug后,首先找到context下的lifecycleProcessor

在这里插入图片描述

3-2 查找beanFactory
  • 然后接着在lifecycleProcessor下找到beanFactory

在这里插入图片描述

3-3 查找singletonObjects
  • 最后找到beanFactory下的singletonObjects

在这里插入图片描述

在singletonObjects下会看到被实例化的user对象,其属性name值为“罗翔老师”

4.Debug测试结论

通过在获取bean前设置断点,然后再进行Debug测试,我们发现,在未获取bean时,user对象就已经被实例化好了

总结因此,在配置文件加载的时候,容器中管理的对象就已经初始化了!

4.2 使用有参构造创建对象

4.2.1 编写beans.xml配置文件

1.使用下标赋值
  • 在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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
	<!--第一种:下标赋值 -->
    <bean id="user" class="com.kuang.pojo.User">
        <constructor-arg index="0" value="罗翔说刑法"/>
    </bean>
</beans>
2.通过类型创建
  • 在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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--第二种方式:通过类型创建-->
    <bean id="user" class="com.kuang.pojo.User">
        <constructor-arg type="java.lang.String" value="luoxiang"/>
    </bean>
</beans>
3. 通过参数名来设置
  • 在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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--第三种方式:直接通过参数名来设置-->
	<bean id="user" class="com.kuang.pojo.User">
        <constructor-arg name="name" value="罗翔"/>
    </bean>
</beans>    

4.2.2 编写MyTest测试类

public class MyTest {
    public static void main(String[] args) {
         //获取beans.xm配置文件,拿到Spring的容器
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //从IOC容器中获取Bean
        User user = (User) context.getBean("user");
        //获取用户名字信息
	    user.show();
    }
}

4.2.3 测试结果

1.使用下标赋值

在这里插入图片描述

结果获取到name值为“罗翔说刑法”的用户信息!

2.通过类型创建

在这里插入图片描述

结果获取到name值为“luoxiang”的用户信息!

3. 通过参数名来设置

在这里插入图片描述

结果获取到name值为“罗翔”的用户信息!

4.3 测试两个用户值是否相等

4.3.1 编写User实体类

package com.kuang.pojo;

public class User {
    private String name;
      //无参构造方法
    public User() {
        System.out.println("User的无参构造");
    }
    //有参构造方法
    public User(String name) {
        this.name = name;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
}

4.3.2 编写beans.xml配置文件

  • 在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
        https://www.springframework.org/schema/beans/spring-beans.xsd">
     <!--第三种方式:直接通过参数名来设置-->
	<bean id="user" class="com.kuang.pojo.User">
        <constructor-arg name="name" value="罗翔"/>
    </bean>
</beans>    

4.3.3 编写MyTest测试类

public class MyTest {
    public static void main(String[] args) {
        //加载beans.xm配置文件,对Bean进行实例化
        ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
        //通过getBean方法,从IOC容器中获取Bean
        User user = (User) context.getBean("user");
               User user = (User) context.getBean("user");
        User user2 = (User) context.getBean("user");
        //判断两个实例化对象的值是否相等
        System.out.println(user == user2);
    }
}
4.3.4 测试结果及结论

在这里插入图片描述

结论:输出值为true,说明前后两个user值相等!

4.2.4 Debug测试

1.设置断点
  • 在第一次获取Bean这行代码前设置断点

在这里插入图片描述

2.Debug测试
  • 右击主方法,选择Debug‘MyTest.main’

在这里插入图片描述

3.Debug测试结果
3-1 查看beanFactory下的singletonObjects
  • Debug后,首先找到context下的lifecycleProcessor,然后接着在lifecycleProcessor下找到beanFactor,最后找到beanFactory下的singletonObjects

在这里插入图片描述

结果经过观察发现,在singletonObjects下存在到被实例化的user对象,其属性name值为“罗翔”

3-2 查看两个user的具体值信息
  • 选择继续向下运行,执行两句获取Bean的代码

在这里插入图片描述

结果分别观察两个user具体的name值,value值以及hashcode值,发现其值完全相同

4.Debug测试结论

总结

  • 通过Debug测试后发现,在未获取bean时,user对象就已经被实例化好了;因此,在获取配置文件的时候,Spring容器被管理的对象就已经初始化了
  • 前后两个user的name和value以及hashcode值完全相同;因此,Spring实例化对象默认的是单例模式

4.4 静态工厂方式实例化

概述

使用静态工厂是实例化Bean的另一种方式,该方式要求自定义一个创建静态工厂的方法,来创建Bean的实例

主要步骤

  • 首先创建一个自定义的MyBeanFactory类,然后定义一个createBean创建Bean对象的静态方法,返回值为创建一个Bean对象
  • 接着在applicationContex.xml配置文件中注册bean节点,需要配置三个属性:id、class和factory-method:id为Bean的类名;class为MyBeanFactory的全路径名;factory-method为创建Bean对象的方法 (由于Spring容器并不知道哪个是所需要的工厂方法,所以使用factory-method来指明)
  • 最后编写测试类,首先定义配置文件路径,然后使用ApplicationContext来加载配置文件,并且对Bean对象进行实例化,最后调用getBean方法来获取Spring容器中由静态工厂创建好的实例化Bean

4.5 实例工厂方式实例化

概述

还有一种实例化Bean的方式,就是使用实例工厂,该方式的工厂类,不再使用静态方法创建Bean实例,而是采用直接创建Bean实例的方式;

同时在配置文件中,需要实例化的Bean也不是通过class属性直接指向其实例化的类,而是通过factory-bean属性配置一个实例工厂,然后使用factory-method属性确定使用工厂中的哪个方法

主要步骤

  • 首先创建一个自定义的MyBeanFactory类,编写该类的无参构造方法,然后定义一个createBean() (创建Bean对象的非静态方法),返回值为创建一个Bean对象
  • 接在在applicationContex.xml配置文件中注册bean节点,需要配置三个属性:id、factory-bean和factory-method:id为Bean的类名;factory-bean为MyBeanFactory的类名(<使用factory-bean属性来配置一个实例工厂);factory-method为创建Bean对象的方法 (由于Spring容器并不知道哪个是所需要的工厂方法,所以使用factory-method来进行指明)
  • 最后编写测试类,首先定义配置文件路径,然后使用ApplicationContext来加载配置文件,并且对Bean对象进行实例化,最后调用getBean方法来获取Spring容器中由实例工厂创建好的实例化Bean

好了,今天的有关Spring基础学习之IOC创建对象的方式的学习就到此结束啦,欢迎小伙伴们积极学习和讨论,喜欢的可以给蜗牛君点个关注,顺便来个一键三连,我们下期见,拜拜啦!


参考视频链接:https://www.bilibili.com/video/BV1WE411d7Dv(【狂神说Java】Spring5最新教程IDEA版通俗易懂)

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

狂奔の蜗牛rz

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值