Bean singleton managed objects and prototype managed objects

Keywords: Spring xml Attribute Java

Object of single case management
When scope = singleton, that is, by default, it is instantiated when the container is started (that is, when the container is instantiated). But we can specify the lazy init = "true" of the bean node to delay the initialization of the bean. In this case, the bean will be initialized only when the bean is first obtained, that is, when the bean is first requested. The configuration is as follows:

<bean id="ServiceImpl" class="cn.csdn.service.ServiceImpl" lazy-init="true"/>  

If you want to apply delay initialization to all default singleton beans, you can set the default lazy init attribute to true in the root node beans, as shown below:

<beans default-lazy-init="true" ...>

By default, Spring creates objects when it reads xml files. When the object is created, the constructor is first invoked and the method specified in the init-method attribute value is called. When an object is destroyed, the method specified in the destroy method property value is called (for example Container.destroy() method). Write a test class. The code is as follows:

public class LifeBean {
    private String name;  

    public LifeBean(){  
        System.out.println("LifeBean()Constructor");  
    }  
    public String getName() {  
        return name;  
    }  

    public void setName(String name) {  
        System.out.println("setName()");  
        this.name = name;  
    }  

    public void init(){  
        System.out.println("this is init of lifeBean");  
    }  

    public void destory(){  
        System.out.println("this is destory of lifeBean " + this);  
    }  
}

life.xml The configuration is as follows:

<bean id="life_singleton" class="com.bean.LifeBean" scope="singleton" 
            init-method="init" destroy-method="destory" lazy-init="true"/>

Test code:

public class LifeTest {
    @Test 
    public void test() {
        AbstractApplicationContext container = 
        new ClassPathXmlApplicationContext("life.xml");
        LifeBean life1 = (LifeBean)container.getBean("life");
        System.out.println(life1);
        container.close();
    }
}

Operation result:

LifeBean()Constructor
this is init of lifeBean
com.bean.LifeBean@573f2bb1
......
this is destory of lifeBean com.bean.LifeBean@573f2bb1

copy
Non singleton managed objects
When scope = prototype, the container will also delay the initialization of the bean. When spring reads the xml file, it does not immediately create the object, but only when it first requests the bean (such as when calling the getBean method). At the first request for every prototype bean, the Spring container calls its constructor to create the object and then calls the method specified in the init-method attribute value. When the object is destroyed, the spring container will not call any methods for us, because it is a non singleton. There are many objects of this type. Once the spring container gives the object to you, it will no longer manage the object.

To test the lifecycle of a prototype bean life.xml The configuration is as follows:

<bean id="life_prototype" class="com.bean.LifeBean" scope="prototype" init-method="init" destroy-method="destory"/>

Test procedure:

public class LifeTest {
    @Test 
    public void test() {
        AbstractApplicationContext container = new ClassPathXmlApplicationContext("life.xml");
        LifeBean life1 = (LifeBean)container.getBean("life_singleton");
        System.out.println(life1);

        LifeBean life3 = (LifeBean)container.getBean("life_prototype");
        System.out.println(life3);
        container.close();
    }
}

Operation result:

LifeBean()Constructor
this is init of lifeBean
com.bean.LifeBean@573f2bb1
LifeBean()Constructor
this is init of lifeBean
com.bean.LifeBean@5ae9a829
......
this is destory of lifeBean com.bean.LifeBean@573f2bb1

It can be found that for a bean with the scope of prototype, its destroy method is not called. If the scope of the bean is set to prototype, the destroy method will not be called when the container is closed. For a prototype scope bean, it is very important that Spring cannot be responsible for the entire life cycle of a prototype bean: after the container initializes, configures, decorates or assembles a prototype instance, it will be handed over to the client, and then the prototype instance will be ignored. Regardless of scope, the container calls the initialization lifecycle callback method for all objects. But for prototype, any configured destruct lifecycle callback method will not be called. It is the responsibility of the client code to clear the objects of the prototype scope and release the expensive resources held by any prototype bean (a feasible way for the Spring container to release the resources occupied by the prototype scope bean is to use the postprocessor of the bean, which holds the references of the bean to be cleared). When it comes to prototype scoped beans, in some ways, you can think of the role of the Spring container as an alternative to Java new operations. Any life cycle issues later than this point in time have to be handled by the client.

The Spring container can manage the life cycle of beans under the singleton scope. In this scope, Spring can know exactly when the beans are created, initialized, and destroyed. For the bean with prototype scope, Spring is only responsible for creation. When the container creates the bean instance, the bean instance is handed over to the client's code management. The Spring container will no longer track its life cycle, and will not manage the life cycle of the bean configured as prototype scope.

Posted by fluvly on Thu, 18 Jun 2020 18:38:31 -0700