Scope and life cycle of Spring~Bean

scope

The scope of a bean is different from the scope of a variable. The scope of a variable refers to the available scope of the variable, while the scope of a bean refers to a certain behavior pattern, which can also be understood as different types of bean instances, such as the singleton function. Domain means that there is only one bean in the entire IoC container, and every operation and return is this bean.

There are currently six types of scopes or scopes in Spring:

scope describe
singleton Singleton scope, there is only one Bean instance in the entire Spring IoC container, and the Bean exists as a singleton
prototype Prototype scope, returns a new instance every time the bean is called from the container. That is, every time getBean is called, it is equivalent to executing the newXxxBean method
request Request scope, each Http request will create a new Bean
session Session scope, the same Http Session shares a Bean, and different Sessions use different Beans
application The global scope, in an Http Servlet Context, defines a bean.
websocket (understand) In the life cycle of a WebSocket, define a Bean instance

There are only the first two scopes in an ordinary spring project , and the last four are the values ​​in spring MVC, which are only applicable to the Spring
WebApplicationContextenvironment of the web.

In normal spring environment:

singleton

The bean declared as singleton has only one instance in the whole spring IoC container. When we get the bean through ApplicationContext.getBean or assemble the bean through the @Autowired annotation, we get the same instance.

Singleton is a singleton mode, that is, the object is automatically created when the container is created. Whether it is used or not, it already exists, and the same object is obtained every time. And singleton is spring's default scope (default scope) .

Usually stateless beans use this scope, and stateful beans use the prototype scope. Stateless means that the properties of the bean object do not need to be updated.

Code example:
Create TestSingleton class as bean:

package com;

import org.springframework.stereotype.Component;

@Component
public class TestSingleton {
    
    
    private String message;
    public void setMessage(String message){
    
    
        this.message  = message;
    }
    public void getMessage(){
    
    
        System.out.println("Your Message : " + message);
    }
}

Try to get two beans at the same time in the test class to see if the output information is the same, the same is the same instance:

import com.Controller.UserController;
import com.TestSingleton;
import com.User.User;
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext context=new ClassPathXmlApplicationContext("a.xml");
        TestSingleton testSingleton_A=(TestSingleton)context.getBean("testSingleton");
        System.out.println("下面是第一个bean的信息:");
        testSingleton_A.setMessage("This is A!");
        testSingleton_A.getMessage();
        TestSingleton testSingleton_B=(TestSingleton)context.getBean("testSingleton");
        System.out.println("下面是第二个bean的信息:");
        testSingleton_B.getMessage();
    }
}

output:

下面是第一个bean的信息:
Your Message : This is A!
下面是第二个bean的信息:
Your Message : This is A!

prototype

Declaring a bean as prototype means that a new instance will be created every time the bean is requested or injected into another bean. When we get the bean through ApplicationContext.getBean or assemble the bean through the @Autowired annotation, we also get a new instance

Prototype is a prototype type, an object is not instantiated when a container is created, but an object is created when we try to obtain a bean, and the object we obtain each time is not the same object.

Stateful beans are usually declared as prototypes , i.e. beans whose object properties need to be updated.

Code example:

Create the TestPrototype class as a bean and set the scope type to prototype by annotating Scope:

package com;

import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;

@Component
@Scope("prototype")
public class TestPrototype {
    
    
    private String message;
    public void setMessage(String message){
    
    
        this.message  = message;
    }
    public void getMessage(){
    
    
        System.out.println("Your Message : " + message);
    }
}

Get two beans in the test class to see if the output information is the same, the same is the same instance, and the difference is a different instance:


import com.TestPrototype;


import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

public class App {
    
    
    public static void main(String[] args) {
    
    
        ApplicationContext context=new ClassPathXmlApplicationContext("a.xml");
        TestPrototype testSingleton_A=(TestPrototype)context.getBean("testPrototype");
        System.out.println("下面是第一个bean的信息:");
        testSingleton_A.setMessage("This is A!");
        testSingleton_A.getMessage();
        TestPrototype testSingleton_B=(TestPrototype)context.getBean("testPrototype");
        System.out.println("下面是第二个bean的信息:");
        testSingleton_B.getMessage();
    }
}

output:

下面是第一个bean的信息:
Your Message : This is A!
下面是第二个bean的信息:
Your Message : null

In the spring web environment:

request, session, applicationthese three scopes are implemented based on Spring WebApplicationContext and can only be used in the web environment (such as in XmlWebApplicationContext)

If these scopes are used in a normal spring environment, that is, a conventional IoC container (such as ClassPathXmlApplicationContext ), the program will throw an IllegalStateException to indicate that an unknown scope is used.

In the web environment, such as using the WebApplicationContext in Spring, we can not only use the two scopes of singleton and prototype, but also three unique scopes: request, session, application.

When using web environment related scopes, some additional configuration must be done in the web container:

  • If you are using the Spring MVC framework, you don't need these configurations, because every http request will DispatcherServletbe processed through, and DispatcherServletthe relevant state has been configured in it.
  • If it is a lower version of the web container, you need to add the following declaration to the configuration XML file:
<web-app>
    ...
    <listener>
        <listener-class>
            org.springframework.web.context.request.RequestContextListener
        </listener-class>
    </listener>
    ...
</web-app>

You can also use RequestContextFilter or ServletRequestListener and other methods in Spring, which will not be described in detail here.

request

request is the request scope .

The bean scope is declared as request, and every time there is an http request, a new instance is created.

When using it, it is also declared in the scope attribute:

<bean id="" class="" scope="request"/>

Assuming that the id of this bean is loginAction, the Spring container will create a new instance every time it uses loginAction to process an Http request, that is, the scope of the bean of loginAction is at the Http Request level.

When an Http request calls a bean whose scope level is Request, each time an Http request is added, Spring will create a new bean. When the request is processed, it will return to destroy the bean, and the developer can arbitrarily change the state of an instance. Because each bean is based on an independent request, other instances cannot see the state of other instances changed by the developer.

session

session is session scoped .

A bean is shared between the same Http Session (session), and different sessions use different beans.

When used, it can be declared in the scope attribute:

<bean id="user" class="" scope="session"/>

Assuming that the id of the bean is user, each time the Spring container calls user, it will create an instance in a session, that is, the bean is at the Http Session level.

All http requests in a Session share a bean, and each time a session is processed with a session-level bean, a new instance is created for each additional session. As with the above request, the developer can modify the state of the bean at will, because each bean is created according to a separate session session, and other beans cannot see the state of this bean.

application

application is the global scope .

How to use:

<bean id="app" class="" scope="application"/>

Assuming the bean's id is app, the Spring container will create a new instance when the app is used throughout the web application. That is, the appBean is at the ServletContext level. .

Global scope and singleton scope are different

As a general property of ServletContext, the global scope is similar to Spring's singleton scope, but there are differences:

  • Different sources : singleton is from Spring Core and application is from Spring Web
  • Different usage : singleton is used for IoC container, and application is used for Servlet container.

How to declare the scope of a bean

via xml configuration file

In the xml configuration file, you can directly set the scope attribute of the bean element.

<?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">
 
     //scope属性
    <bean id="SingletonBean" class="com.spring.demo.SingletonBean" scope="prototype"></bean>
   
</beans>

via annotation

Add the annotation to the bean:

package com.spring.demo;
 
import org.springframework.context.annotation.Scope;;
import org.springframework.stereotype.Component;
 
@Component("SingletonBean")
@Scope("prototype")
public class SingletonBean {
    
    
    private String message;
    public void setMessage(String message){
    
    
        this.message  = message;
    }
    public void getMessage(){
    
    
        System.out.println("Your Message : " + message);
    }
}

@Component("SingletonBean") identifies the class as a bean, and @Scope("prototype") identifies the bean's scope as the prototype type.

life cycle

The life cycle of a bean refers to the process of a bean object from "birth" to "destruction", which can be expressed as:
Bean definition --> Bean initialization --> Bean use --> Bean destruction.

The specific process is as follows:

1. Instantiate the Bean and allocate some memory space for the Bean.
2. Set properties, inject or assemble beans
3. Initialize:

  • Implement various notification (Aware) methods, such as BeanNameAware, BeanFactoryAware, BeanFactoryAware, ApplicationContextAware, etc.
  • Execute the BeanPostProcessorinitialization pre-method
  • Execute the @PostConstruct initialization method and execute it after injecting dependencies
  • Execute custom inti-method methods (optional)
  • Execute the BeanPostProcessorinitialization post method.
    4. Use Bean
    5. Destroy Bean

The flow chart is as follows:
insert image description here

The difference between initialization and instantiation:

Instantiation and property setting are system events of Java, which cannot be interfered and modified, while initialization is customized by the developer. After the instantiation is completed, these customized initialization contents will be executed before the class is loaded.

Article reference: https://blog.csdn.net/kongmin_123/article/details/82048392

Guess you like

Origin blog.csdn.net/Merciful_Lion/article/details/124082956