SpringBoot

Spring容器创建对象的时机

2020-03-25  本文已影响0人  HeloWxl

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");
  }
  
}
 /**
     * 只启动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属性

<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
    }

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中的生命周期

/**
 * 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...");
    }
}
    <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();
    }
上一篇 下一篇

猜你喜欢

热点阅读