Analysis of Spring life cycle

insert image description here

foreword

The Spring Framework is a very popular Java enterprise application framework that has become the technology of choice in many production environments. It provides a convenient way to help developers build scalable and modular enterprise applications. In the Spring framework, the Bean life cycle is a very important part, which is responsible for the creation and destruction of Beans.

A complete Spring Bean life cycle

The complete life cycle of a Bean in the Spring framework includes:

  1. Instantiate the bean
  2. Set object properties
  3. Executes a user-defined initialization method on a bean
  4. Beans are available
  5. close container

Instantiate the bean

In Spring, there are two main ways to instantiate a Bean: using a constructor to instantiate and using a static factory method to instantiate.

Constructor instantiation is the way to create a Bean object using the constructor of the class. In a Spring configuration file, a bean's constructor arguments can be specified through the constructor-arg subelement of the element.

The instantiation of the static factory method refers to calling the static factory method to create the Bean object when the BeanFactory creates the Bean instance. In the Spring configuration file, you can specify the Bean factory class and factory method through the class attribute and factory-method attribute of the element.

It should be noted that in Spring, the Bean does not directly enter the use state after instantiation, but is stored in the BeanFactory, waiting to be used by other Beans. If the bean is not configured to be singleton scoped, a new bean instance will be created each time the bean is used.

When Bean is instantiated, there are several important interfaces, which we can look at.

1. BeanFactoryPostProcessor

BeanFactoryPostProcessor allows developers to configure or modify the Bean before the Bean Factory creates it, and it can also perform some customization operations before the Bean is instantiated. Through the BeanFactoryPostProcessor interface, developers can access the BeanFactory in the Spring container to change the configuration information of the Bean, such as changing the scope of a Bean from singleton to prototype.

The BeanFactoryPostProcessor interface includes a method postProcessBeanFactory( ConfigurableListableBeanFactory beanFactory ), which receives a ConfigurableListableBeanFactory object as a parameter, which can be used to modify the configuration of the BeanFactory. Implementing a custom BeanFactoryPostProcessor is very simple: just create a class that implements the interface and declare the bean in the Spring configuration file.

2. BeanPostProcessor

When we create a bean, the Spring framework will execute the corresponding methods in the order of the life cycle methods of the bean. The BeanPostProcessor interface defines two methods, beforeInitialization and afterInitialization, for processing before and after Bean initialization.

The main function of BeanPostProcessor is to post-process Bean instances. After the Bean instance is created, the BeanPostProcessor instance will perform some additional processing, or modification, on the Bean. For example, developers can use BeanPostProcessor to implement some non-intrusive centralized logging or initialize some property values ​​before Bean assembly, and set proxy for Bean.

Set object properties

Setting object properties is a phase in the Spring Bean life cycle. At this stage, the Spring framework will set properties for the object according to the configuration information of the Bean and assemble it into the application.

The specific implementation method is to add attribute elements in the configuration information of the Bean, which is used to configure the attribute values ​​of the object. For example:

<bean id="exampleBean" class="com.example.Example">
    <property name="name" value="John Doe" />
    <property name="age" value="30" />
</bean>

In the above example, we defined a Bean named exampleBean whose class is com.example.Example. We set two properties of the object using the element: name and age. It can be seen that we specify the attribute name to be set through the name attribute, and specify the attribute value to be set through the value attribute. The Spring framework will use the reflection mechanism to call the setter method of the object and set the property value as a parameter.

In addition, when using annotations to configure beans, you can also use @Autowired annotations or @Resource annotations to automatically assemble properties of objects. These annotations can automatically find adapted beans for assembly according to Type or Name, thereby reducing the work of manually configuring Bean properties. For example:

@Component
public class ExampleComponent {
    
    
    @Autowired
    private ExampleBean exampleBean;

    public void doSomething() {
    
    
        // 使用exampleBean对象执行一些操作
    }
}

@Component
public class ExampleBean {
    
    
    private String name;
    private int age;

    public void setName(String name) {
    
    
        this.name = name;
    }

    public void setAge(int age) {
    
    
        this.age = age;
    }
}

In the above example, we defined an ExampleComponent component injected using the @Autowired annotation, and injected its property exampleBean into an ExampleBean object. When the Spring framework starts, it will automatically instantiate the object for the ExampleComponent component, and call the setter method to inject the exampleBean object into the ExampleComponent.

Executes a user-defined initialization method on a bean

The implementation of user-defined initialization methods for beans is implemented in the Spring framework through the life cycle callback methods of beans. Specific steps are as follows:

1. Implement InitializingBean

InitializingBean is one of the very important interfaces in the Spring framework, which defines the operations to be performed after the Bean is initialized. After the BeanFactory completes the configuration of the Bean instance and the pre- and post-processing work of adding the Bean instance, the Spring container will call the afterPropertiesSet method of the InitializingBean interface to initialize and execute the Bean.

In the Spring container, the class that implements the InitializingBean interface becomes very important, which allows developers to control the complete life cycle of the Bean. Developers can use the afterPropertiesSet method to initialize some data for the Bean or modify/verify some dependencies that have been set.

Implement the InitializingBean interface in the Bean class, which defines an afterPropertiesSet() method, which will be called after the Bean initialization is completed.

public class MyBean implements InitializingBean {
    
    
    // ...
    @Override
    public void afterPropertiesSet() throws Exception {
    
    
        // 在这里编写Bean初始化的逻辑
        // ...
    }
    // ...
}

2. Use @PostConstruct annotation

You can also use the @PostConstruct annotation to execute the specified method after the Bean is initialized, for example:

public class MyBean {
    
    
    // ...
    @PostConstruct
    public void init() {
    
    
        // 在这里编写Bean初始化的逻辑
        // ...
    }
    // ...
}

3. Specify the init method

You can also specify the method called when the Bean is initialized in the XML configuration file, for example:

<bean id="myBean" class="com.example.MyBean" init-method="init"/>

Among them, the init-method attribute specifies the method name to be called when the Bean is initialized.

The above are three commonly used ways to implement user-defined initialization methods for beans, and you can choose one of them according to specific situations.

Beans are available

Simply put, in the Spring life cycle, Bean availability is triggered at a certain point in the BeanFactory startup phase, indicating that the Bean has completed all initialization work and can be called and used by other Beans. In this state, the Bean is already in normal operation and can provide external services or process business logic.

Here is a sample code available for a simple Spring lifecycle bean. First, we define a BeanLifeCycleDemoclass called , and specify initialization and destruction methods. code show as below:

public class BeanLifeCycleDemo {
    
    
    private String message;

    public void init() {
    
    
        System.out.println("Bean is being initialized.");
        this.message = "Hello, world!";
    }

    public void destroy() {
    
    
        System.out.println("Bean is being destroyed.");
    }

    public String getMessage() {
    
    
        return this.message;
    }

    public void setMessage(String message) {
    
    
        this.message = message;
    }
}

Next, we need to declare the Bean of this class in the Spring configuration file and specify its initialization and destruction methods. The configuration file is beans.xml, the code is as follows:

<bean id="beanLifeCycleDemo" class="com.example.BeanLifeCycleDemo"
      init-method="init" destroy-method="destroy">
    <property name="message" value="Hello, world!"/>
</bean>

In this example, we use Spring's dependency injection feature, setting the property messageto Hello, world!. At the same time, we specified the Bean's initialization method as init(), and the destruction method as destroy().

Finally, we create a test class AppTestand test the output Bean's information in it. code show as below:

public class AppTest {
    
    
    public static void main(String[] args) {
    
    
        ClassPathXmlApplicationContext context =
                new ClassPathXmlApplicationContext("beans.xml");
        BeanLifeCycleDemo bean = context.getBean("beanLifeCycleDemo", BeanLifeCycleDemo.class);
        System.out.println(bean.getMessage());
        context.close();
    }
}

In this test class, we use ClassPathXmlApplicationContextthe class to create the Spring container and context.getBean()get the Bean instance through the method. Then, we output the Bean's information, that is Hello, world!, and call context.close()the method to destroy the Bean. In the console output, we can see the initialization method "Bean is being initialized." and the destruction method "Bean is being destroyed." information.

Through the above example, we can see that in the Spring life cycle, Bean availability is triggered after the Bean initialization is completed. In this state, we can operate on the Bean, including calling its methods, obtaining its properties, and so on.
insert image description here

close container

In the Spring framework, the last stage of the Bean life cycle is to close the container, that is, when the application finishes running, the close() method of the ApplicationContext should be called to release all resources and the memory occupied by the Bean. When the ApplicationContext is closed, it notifies the beans so they can respond to the shutdown.

Following are the steps involved in the bean lifecycle when the container is shut down:

  1. When the BeanFactory is closed, the destroy() method of all DisposableBean instances will be called.

DisposableBean is a key interface in the Spring framework. It defines what the bean is to do when it is destroyed. After a bean is instantiated by the container, before the container destroys the bean, the interface implemented by the bean will be called. The most common actions include closing database connections or stopping tasks executed against message queues. Implementing DisposableBean is important if there is a need to release certain resources before the bean is destroyed.

  1. If the Bean implements the DisposableBean interface, the destroy() method is called. This method allows the bean to clean up any resources that have been initialized or logged while the application is running.

  2. Calls any custom destroy methods defined in the bean definition. Custom destroy methods can be defined by specifying the destroy-method attribute. For example:

    <bean id="myBean" class="com.example.MyBean" destroy-method="cleanup"/>
    

    The cleanup() method here will be called when the container is shut down.

  3. Close the inner bean container.
    If the bean is a subcontainer of the ApplicationContext, the bean in the subcontainer is closed first. The ApplicationContext itself is then closed to ensure that all beans are in a destroyed state.

It should be noted that when the application is closed, all resources, such as database connections, file handles, etc., must be effectively released. Therefore, it is very important to implement destroy() and a custom destroy method. These methods ensure that the bean releases all resources and exits properly when the application is shut down.

In addition to using the destruction method, you can also use annotations to mark the Bean's initialization and destruction methods. @PostConstruct and @PreDestroy are built-in annotations in the two Spring frameworks. These annotations can be used on any method, as long as they conform to the Bean specification.

The @PostConstruct annotation is called after the Bean is initialized, and the @PreDestroy annotation is called before the Bean is destroyed. When using annotations, you only need to define the methods that need to be executed, and you can achieve the effects of Bean initialization and destruction at the same time.
insert image description here

in conclusion

Spring's Bean life cycle can be divided into two stages: BeanFactory preparation and BeanFactory startup, in which Bean creation, initialization, destruction and other processes are completed within this time period. In the BeanFactory preparation phase, the Spring container initializes the BeanFactory, including loading configuration files, instantiating the Bean factory, and so on. At this stage, interfaces such as Bean Factory Post Processor (BFPP) and Bean Post Processor (BPP) are called to preprocess FactoryBean and ordinary beans. In the BeanFactory startup phase, the Spring container will instantiate all beans after startup, and initialize the beans according to the defined attributes, dependencies and other settings. In this process, the constructor and initialization method of the Bean are called, operations such as dependency injection are performed on the Bean, and the state that the Bean can be used is also triggered. When the container is shut down, Spring will call the Bean's destruction method to do some cleanup.

Guess you like

Origin blog.csdn.net/m290345792/article/details/131108648