Abstract: When using Spring for IOC configuration, the configuration and use of beans have always been an important part. Meanwhile, how to use and create bean objects reasonably is also the part that people need to pay attention to when learning and using Spring. So in this article, I’m going to talk about the scope and lifecycle of beans in Spring.

This article is from The Huawei Cloud community “In Detail the Scope and Lifecycle of Beans in Spring”, the original author: Grey Monkey.

When using Spring for IOC configuration, the configuration and use of beans have always been an important part. Meanwhile, how to use and create bean objects reasonably is also the part that people need to pay attention to when learning and using Spring. So in this article, I’m going to talk about the scope and lifecycle of beans in Spring.

The scope of the Bean

First, let’s talk about the scope of beans

Normally, the configuration information we write in the IOC container is created when our IOC container is running, which results in that when we get bean objects through the IOC container, we usually get singleton bean objects

This means that no matter how many getBean() methods we use, the same Javabeans we get will always be the same object, the single instance Bean, which will be shared by the entire project.

In Spring, you can set the scope of a bean in the element’s Scope attribute to determine whether the bean is single-instance or multi-instance. The Scope attribute takes four parameters. See the following figure for details:

1. Single instance Bean declaration

By default, Spring creates only one instance of each bean declared in the IOC container, which is shared across the IOC container: all subsequent getBean() calls and bean references return this unique bean instance. This scope is called a Singleton and is the default scope for all beans. That’s a single instance.

To verify this statement, we create a single instance of bean in IOC and get the bean object for comparison:

<! >< span style =" box-sizing: border-box; color: RGB (50, 50, 50); line-height: 22px; font-size: 14px! Important; word-break: break-word! Important;"Copy the code

Test whether the obtained single instance bean is the same:

@test public void test09() {// Book book03 = (Book)iocContext3.getBean("book02"); Book book04 = (Book)iocContext3.getBean("book02"); System.out.println(book03==book04); }Copy the code

That’s true

2. Multi-instance Bean declaration

And since there are single instances, there must be multiple instances. We can set the Prototype parameter to the Scope property of the Bean object to indicate that the instance is multi-instance, get the multi-instance bean in the IOC container, and compare the obtained multi-instance bean

<! 1, the container is not created when the container is created. < span style =" box-sizing: border-box; color: RGB (74, 74, 74); line-height: 22px; font-size: 13px! Important; word-break: break-word! Important;"Copy the code

Test whether the obtained multi-instance bean is the same:

@test public void test09() {// Book book01 = (Book)iocContext3.getBean("book01"); Book book02 = (Book)iocContext3.getBean("book01"); System.out.println(book01==book02); }Copy the code

That’s false

This illustrates that the bean objects created through multiple instances are different.

Note here:

There is also a difference between singleton and multi-instance bean creation. When the bean is scoped as a singleton, Spring creates the object instance of the bean when the IOC container object is created. When the bean is prototype scoped, the IOC container creates an instance object of the bean when it gets an instance of the bean.

Second, the lifecycle of the Bean

1, bean initialization and destruction

Each bean object we create in IOC has a specific lifecycle. Spring’s IOC container manages the lifecycle of beans. Spring allows specific tasks to be performed at specific points in the bean lifecycle. Such as methods that are executed when the bean is initialized and methods that are executed when the bean is destroyed.

The Spring IOC container manages the bean lifecycle in six steps:

1. Create bean instances via constructor or factory methods

2. Set values for bean properties and references to other beans

3. Call the bean’s initialization method

4. Beans can be used normally

5. Call the bean’s destruction method when the container is closed

What about the methods that are executed when the bean is initialized and destroyed?

First we should add methods inside the bean class that are executed at initial and destruction. Look at this Javabean:

package com.spring.beans; public class Book { private String bookName; private String author; Public void myInit() {system.out.println (" Book bean was created "); Public void myDestory() {system.out.println (" Book bean was destroyed "); } public String getBookName() { return bookName; } public void setBookName(String bookName) { this.bookName = bookName; } public String getAuthor() { return author; } public void setAuthor(String author) { this.author = author; } @Override public String toString() { return "Book [bookName=" + bookName + ", author=" + author + "]"; }}Copy the code

When we configure the bean, we can specify initialization and destruction methods for the bean through the init-method and destroy-method properties

<! -- Set the lifecycle of the bean destory-method: End the call to the method init-method: </bean> <bean id="book01" class="com.spring.beans.Book" destruct-method ="myDestory" init-method="myInit"></bean>Copy the code

This will execute the corresponding methods when we create and destroy bean objects through the IOC container

But there’s one thing to note:

As we said above, the creation time of a single-instance bean is different from that of a multi-instance bean, so the execution time of their initial and destruction methods is slightly different.

The life cycle of a bean under a single instance

Container start — > initialize method — > (container close) destroy method

Life cycle of beans under multiple instances

Container start — > call bean — > Initialize method — > Container close (destroy method does not execute)

2. Post processor for beans

What is the bean’s post-processor? The Bean postprocessor allows additional processing of the bean before and after the invocation of the initialization method

The bean postprocessor processes all bean instances in the IOC container one by one, rather than a single instance.

Its typical application is to check the correctness of bean properties or to change bean properties according to specific standards.

The bean postprocessor needs to implement the interface:

Org. Springframework. Beans. Factory. Config. BeanPostProcessor.

Before and after the initialization method is called, Spring will pass each bean instance to the following methods of the above interface:

PostProcessBeforeInitialization (Object, String) before invoking it

Call after postProcessAfterInitialization (Object, String)

Here is a post-processor that implements this interface:

package com.spring.beans; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * test the bean's backend handler ** Note that this is for the bean and beanName, not for arg0 and arg1. Need to bind the corresponding source jar package * * / public class MyBeanPostProcessor implements the BeanPostProcessor {/ * * * postProcessBeforeInitialization * Override public Override public Override public Override public Override public Override public Override public Override public Override postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {// TODO auto-generated Method Stub System.out.println(" ["+ BeanName +"..." ); return bean; PostProcessAfterInitialization} / * * * * executed after initialization method * Object String bean * beanName XML containers that are defined in the bean name * * / @ Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {// TODO auto-generated Method Stub System.out.println(" ["+ BeanName +"..." ); return bean; }}Copy the code

Add the post-processor to the IOC container:

<! - test the bean's rear processor - > < bean id = "beanPostProcessor" class = "com. Spring. Beans. MyBeanPostProcessor" > < / bean >Copy the code

Since our bean object is now singleton, the bean object is created directly at the container runtime, and its post-handler and initialization methods are also executed, and the destruction method is executed when the container is destroyed. We tested it as follows:

/ / * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * bean lifecycle * * * * * * * * * * * * / / because the ApplicationContext is a top-level interface, there is no destroy method close, So you need to use it a child of the interface for receiving ConfigurableApplicationContext iocContext01 = new ClassPathXmlApplicationContext (" ioc1. XML "); @Test public void test01() { iocContext01.getBean("book01"); iocContext01.close(); }Copy the code

Running result:

To summarize the post-processor execution:

1. Create bean instances via constructor or factory methods

2. Set values for bean properties and references to other beans

3. Pass the bean instance to rear bean processors * * postProcessBeforeInitialization () method

4. Call the bean’s initialization method

5. Pass the bean instance to rear bean processors * * postProcessAfterInitialization () method

6. The bean is ready to use

7. Call the bean’s destruction method when the container is closed

So the life cycle of the bean after adding the bean handler is:

Container start — before… — > initialization method — > after… — > (container closed) destruction method

Click follow to learn about the fresh technologies of Huawei Cloud