美文网首页SpringBoot
Spring容器创建对象的时机

Spring容器创建对象的时机

作者: HeloWxl | 来源:发表于2020-03-25 12:01 被阅读0次

Spring容器创建对象的时机

1、默认的情况下,启动spring容器时,编创建对象,(遇到bean便创建对象)

测试:
在HelloIoc.java中添加构造方法

/**
 * @author wangxl
 * @ClassName HelloIoc
 * @Description TODO
 * @date 2019/10/14 17:29
 */
public class HelloIoc {

  //默认构造函数
  public HelloIoc() {
    System.out.println("Hello default Constructor");
  }
  
  /**
   * sayHello方法
   */
  public void sayHello() {
    System.out.println("Hello IOC");
  }
  
}
  • 在 applicationContext.xml 文件中添加 bean(由于上面我们通过三种方式来创建对象了,里面已经有三个bean了)
  • 启动 Spring 容器,查看无参构造函数的打印次数
    测试:
 /**
     * 只启动Spring容器
     */
    @Test
    public void whenCreateObject(){
        ApplicationContext context =
            new ClassPathXmlApplicationContext("applicationContext.xml");
    }

结果:

十月 17, 2019 2:00:08 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5ccd43c2: startup date [Thu Oct 17 14:00:08 CST 2019]; root of context hierarchy
十月 17, 2019 2:00:09 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Hello default Constructor
Hello default Constructor
实例工厂方法构造函数
Hello default Constructor

2、在spring的配置文件bean中有一个属性 lazy-init="default/true/false"

①、如果lazy-init为"default/false"在启动spring容器时创建对象(默认情况)
②、如果lazy-init为"true",在context.getBean时才要创建对象


image.png

测试结果:

如果lazy-init为"default/false"在启动spring容器时创建对象(默认情况),没有getBean()

十月 17, 2019 2:02:45 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5ccd43c2: startup date [Thu Oct 17 14:02:45 CST 2019]; root of context hierarchy
十月 17, 2019 2:02:46 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Hello default Constructor
实例工厂方法构造函数
Hello default Constructor

当lazy-init = "true" 时,我们执行getbean()方法,Spring容器才会去创建对象。

    @Test
    public void iocTest() {
        //1.启动spring容器
        ApplicationContext applicationContext = new ClassPathXmlApplicationContext("applicationContext.xml");
        //2.从spring容器中取出数据
        HelloIoc ioc = (HelloIoc) applicationContext.getBean("helloIoc");
    }

测试结果:

十月 17, 2019 2:05:22 下午 org.springframework.context.support.AbstractApplicationContext prepareRefresh
信息: Refreshing org.springframework.context.support.ClassPathXmlApplicationContext@5ccd43c2: startup date [Thu Oct 17 14:05:22 CST 2019]; root of context hierarchy
十月 17, 2019 2:05:23 下午 org.springframework.beans.factory.xml.XmlBeanDefinitionReader loadBeanDefinitions
信息: Loading XML bean definitions from class path resource [applicationContext.xml]
Hello default Constructor
实例工厂方法构造函数
Hello default Constructor
Hello default Constructor

小结:

第一种情况下:

在启动Spring容器的时候,会检查 Spring容器的配置文件的正确性,如果再结合tomcat,当spring容器不能正常启动时,整个tomcat就不能正常启动。但是这样的缺点就是把一些bean过早的放在了内存中,如果有数据的话,则对内存就是一个消耗。

在第二种情况下:

可以较少内存消耗,但是不容易发生错误。

Spring的Bean中的 scope属性

  • 1、默认的scope的值是singleton,即产生的对象是单例的。
    applicationContext.xml 文件中配置:
<bean id="helloIoc" scope="singleton" class="com.ys.ioc.HelloIoc" ></bean>

测试验证

//spring 容器默认产生对象是单例的 scope="singleton"
    @Test
    public void test_scope_single_CreateObject(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloIoc hello1 = (HelloIoc) context.getBean("helloIoc");
        HelloIoc hello2 = (HelloIoc) context.getBean("helloIoc");
        System.out.println(hello1.equals(hello2)); //true
    }
  • 2、scope=“prototype”
     多例模式,并且spring容器启动的时候并不会创建对象,而是在得到 bean 的时候才会创建对象

applicationContext.xml 文件中配置:

<bean id="helloIoc" scope="prototype" class="com.ys.ioc.HelloIoc" ></bean>

测试验证

///spring 容器默认产生对象是单例的 scope="prototype"
    @Test
    public void test_scope_prototype_CreateObject(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        HelloIoc hello1 = (HelloIoc) context.getBean("helloIoc");
        HelloIoc hello2 = (HelloIoc) context.getBean("helloIoc");
        System.out.println(hello1.equals(hello2)); //false
    }

总结:

在单例的模式下,启动spring容器,便会创建对象;在多例模式下,启动容器不会创建对象,获得bean的时候才会创建对象。

Spring的Bean中的生命周期

  • 创建 SpringLifeCycle.java
/**
 * Spring 容器的生命周期
 * @author hadoop
 *
 */
public class SpringLifeCycle {
    public SpringLifeCycle(){
        System.out.println("SpringLifeCycle");
    }
    //定义初始化方法
    public void init(){
        System.out.println("init...");
    }
    //定义销毁方法
    public void destroy(){
        System.out.println("destroy...");
    }
     
    public void sayHello(){
        System.out.println("say Hello...");
    }
}
  • applicationContext.xml
    <bean id="springLifeCycle" init-method="init" destroy-method="destroy" class="com.ys.ioc.SpringLifeCycle"></bean>

  • 测试
//spring 容器的初始化和销毁
    @Test
    public void testSpringLifeCycle(){
        ApplicationContext context = new ClassPathXmlApplicationContext("applicationContext.xml");
        SpringLifeCycle hello = (SpringLifeCycle) context.getBean("springLifeCycle");
         
        hello.sayHello();
         
        //销毁spring容器
        ClassPathXmlApplicationContext classContext = (ClassPathXmlApplicationContext) context;
        classContext.close();
    }
  • 控制台打印如下:


    image.png
  • 分析:spring 容器的声明周期
    1、spring容器创建对象
    2、执行init方法
    3、调用自己的方法
    4、当spring容器关闭的时候执行destroy方法
     注意:当scope为"prototype"时,调用 close() 方法时是不会调用 destroy 方法的

相关文章

  • Spring容器创建对象的时机

    本文是接着这篇文章写的。Spring-IOC创建对象的三种方式 参考: Spring详解(二)------IOC控...

  • Spring 学习笔记(二):Spring 容器以及 bean

    Spring 容器 在 Spring 应用中,应用对象生存于 Spring 容器中,Spring 容器负责创建对象...

  • spring 学习02

    Spring 容器 在Spring 应用中,你的应用对象生存在Spring容器中,Spring 容器负责创建对象,...

  • spring scope

    singleton:单例。默认对象创建时机为容器加载时机prototype:多例。默认对象创建时机为我们调用该对象...

  • 2.Spring IoC 容器

    1.Spring IoC 容器 IoC 容器 Spring 容器是 Spring 框架的核心。容器将创建对象,把它...

  • Spring知识清单

    1什么是Spring Bean容器? 用于创建bean对象,管理bean对象的那个容器。 2Spring Bean...

  • Spring Ioc DI

    Spring Ioc 容器是Spring框架的核心。只需要进行简单的容器配置,就能将创建对象,使用对象,销毁对象联...

  • spring_IOC总结(二)--xml依赖注入

    spring的bean对象--依赖注入 spring 创建bean对象细节 配置spring核心容器xml配置文件...

  • Spring--IOC容器——对象创建

    一.IOC容器--spring 是spring核心内容。作用: 创建对象 和 处理对象的依赖关系 二.IOC容器创...

  • 容器

    在基于Spring的应用中,你的应用对象生存于Spring容器(container)中。Spring容器负责创建对...

网友评论

    本文标题:Spring容器创建对象的时机

    本文链接:https://www.haomeiwen.com/subject/qlwmmctx.html