The life cycle of beans in Spring
1. What is the life cycle of beans in Spring
Spring's biggest feature is Bean oriented (BOP) programming. The Bean managed by spring is a POJO, that is, a simple JavaBean (Bean that does not need to implement any specification). Spring provides many methods to enhance the functions of the managed Bean objects, including the control of the life cycle.
2. Preparation phase before bean creation
Before the Bean is created by Spring, the IoC container will be instantiated first to find the configuration information of all beans managed by Spring. At the same time, beanfactoryprocessor, InstantiationAwareBeanPostProcessor, BeanPostProcessor and other processors will be instantiated.
Interface | explain |
---|---|
BeanFactoryPostProcessor | This interface has only one beanfactoryprocessor () method. After BeanFactory is initialized, you can modify the metadata of the Bean. At this time, the Bean has not been instantiated. |
InstantiationAwareBeanPostProcessor | The implementation class of the interface will only be instantiated in the preparation stage and will not call any methods. |
BeanPostProcessor | The implementation class of the interface will only be instantiated in the preparation stage and will not call any methods. |
2.1 code demonstration
package com.wxw.processor.ioc; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanDefinition; import org.springframework.beans.factory.config.BeanFactoryPostProcessor; import org.springframework.beans.factory.config.ConfigurableListableBeanFactory; public class WxwBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public WxwBeanFactoryPostProcessor() { System.out.println("Call[ BeanFactoryPostProcessor]Construction method!!!"); } @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException { System.out.println("Call[ BeanFactoryPostProcessor]Class postProcessBeanFactory method!!!"); // Here you can modify the metadata of the Bean BeanDefinition userBean = configurableListableBeanFactory.getBeanDefinition("userBean"); userBean.getPropertyValues().addPropertyValue("age","28"); } }
package com.wxw.processor.instantiation; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; public class WxwInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { public WxwInstantiationAwareBeanPostProcessor() { System.out.println("Call[ InstantiationAwareBeanPostProcessor]Construction method!!!"); } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("Call[ InstantiationAwareBeanPostProcessor]of Before method!!!"); return null; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("Call[ InstantiationAwareBeanPostProcessor]of After method!!!"); return false; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { return null; } }
package com.wxw.processor.initialize; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class WxwBeanPostProcessor implements BeanPostProcessor { public WxwBeanPostProcessor(){ System.out.println("Call[ BeanPostProcessor]Construction method!!!"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Call[ BeanPostProcessor]Yes[ Before]method!!!"); return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Call[ BeanPostProcessor]Yes[ After]method!!!"); return null; } }
package com.wxw.test; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestClass { @Test public void test1(){ System.out.println("=====================IoC Container initialization begin========================="); ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml"); System.out.println("=====================IoC Container initialization end========================="); } }
The operation results are as follows:
=====================IoC Container initialization begin========================= Call[ BeanFactoryPostProcessor]Construction method!!! Call[ BeanFactoryPostProcessor]Class postProcessBeanFactory method!!! Call[ InstantiationAwareBeanPostProcessor]Construction method!!! Call[ BeanPostProcessor]Construction method!!! =====================IoC Container initialization end=========================
2.2 sequence diagram
3. Bean instantiation stage
Bean s in Spring will be processed by the relevant methods of the instantiaawarebeanpostprocessor processor in the instantiation phase.
Interface | explain |
---|---|
InstantiationAwareBeanPostProcessor | The interface has three methods: 1. postProcessBeforeInstantiation(): this method will be called before Bean is instantiated, if the method returns a non empty object. It will skip the process of Spring creating beans (including dependency injection, initialization, etc.), directly execute the post processor of BeanPostProcessor, and then return this object. If the method returns null, it will execute the normal process of Spring creating beans. 2. postProcessAfterInstantiation(): after the Bean is instantiated, it will be invoked before it is injected. If the method returns to false, it will exit the populateBean() method directly and make the current Bean dependency injection step short. If the method returns true, the normal process will be executed. 3. postProcessProperties(): this method is executed After the After method returns true. You can process the properties of the Bean before Spring sets the property value of the Bean. |
3.1 code demonstration
package com.wxw.processor.instantiation; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor; import java.lang.reflect.Constructor; public class WxwInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor { public WxwInstantiationAwareBeanPostProcessor() { System.out.println("Call[ InstantiationAwareBeanPostProcessor]Construction method!!!"); } @Override public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException { System.out.println("Call[ InstantiationAwareBeanPostProcessor]of Before method!!!"); Object obj = null; try { Constructor<?> constructor = beanClass.getConstructor(String.class, Integer.class); obj = constructor.newInstance("wxw",20); } catch (Exception e) { e.printStackTrace(); } return obj; } @Override public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException { System.out.println("Call[ InstantiationAwareBeanPostProcessor]of After method!!!"); return false; } @Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) throws BeansException { System.out.println("Call[ InstantiationAwareBeanPostProcessor]of postProcessProperties method!!!"); return pvs; } }
package com.wxw.pojo; import lombok.Data; import org.springframework.beans.factory.InitializingBean; @Data public class UserBean implements InitializingBean { private String name; private Integer age; public UserBean() { System.out.println("Call[ UserBean]Construction method of!!!"); } public UserBean(String name, Integer age) { this.name = name; this.age = age; } public void setName(String name) { System.out.println("Call[ UserBean]Yes[ setName]method!!!"); this.name = name; } public void setAge(Integer age) { System.out.println("Call[ UserBean]Yes[ setAge]method!!!"); this.age = age; } @Override public String toString() { return "UserBean{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public void afterPropertiesSet() throws Exception { System.out.println("[UserBean]Yes[ init]Method execution!!!"); } }
The operation results are as follows:
=====================IoC Container initialization begin========================= Call[ BeanFactoryPostProcessor]Construction method!!! Call[ BeanFactoryPostProcessor]Class postProcessBeanFactory method!!! Call[ InstantiationAwareBeanPostProcessor]Construction method!!! Call[ BeanPostProcessor]Construction method!!! =====================IoC Container initialization end========================= Call[ InstantiationAwareBeanPostProcessor]of Before method!!! Call[ BeanPostProcessor]Yes[ After]method!!!
3.2 sequence diagram
4. Bean initialization phase
In the Bean initialization phase, the related methods of Aware interface implementation class, BeanPostProcessor processing, setBeanFactory method of InitializingBean interface and init method method configured in xml will be executed.
Interface | explain |
---|---|
Aware | The class implementing the interface will make the class aware of some properties, such as BeanFactoryAware, BeanNameAware, etc |
BeanPostProcessor | The interface has two methods: 1. postProcessBeforeInitialization: executed before the Bean initializes the callback function 2. postProcessAfterInitialization: executed after the Bean initializes the callback function |
InitializingBean | setBeanFactory method: initialization callback function of Bean |
Init method configuration method | Like the InitializingBean interface method, initialize the callback function |
4.1 code demonstration
UserBean class:
package com.wxw.pojo; import lombok.Data; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.InitializingBean; @Data public class UserBean implements InitializingBean, BeanFactoryAware { private String name; private Integer age; private BeanFactory beanFactory; public UserBean() { System.out.println("Call[ UserBean]Construction method of!!!"); } public UserBean(String name, Integer age) { this.name = name; this.age = age; } public void setName(String name) { System.out.println("Call[ UserBean]Yes[ setName]method!!!"); this.name = name; } public void setAge(Integer age) { System.out.println("Call[ UserBean]Yes[ setAge]method!!!"); this.age = age; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("Call[ BeanFactoryAware]Yes[ setBeanFactory]method!!!"); this.beanFactory = beanFactory; } @Override public String toString() { return "UserBean{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public void afterPropertiesSet() throws Exception { System.out.println("[InitializingBean]Yes[ init]Method execution!!!"); } public void init(){ System.out.println("[init-method]Configured[ init]Method execution!!!"); } }
spring-config.xml
<?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"> <bean id="userBean" class="com.wxw.pojo.UserBean" lazy-init="true" init-method="init" scope="singleton"> <property name="name" value="Wxw"/> <property name="age" value="18"/> </bean> <bean id="wxwBeanFactoryPostProcessor" class="com.wxw.processor.ioc.WxwBeanFactoryPostProcessor"></bean> <bean id="wxwInstantiationAwareBeanPostProcessor" class="com.wxw.processor.instantiation.WxwInstantiationAwareBeanPostProcessor"></bean> <bean id="wxwBeanPostProcessor" class="com.wxw.processor.initialize.WxwBeanPostProcessor"></bean> </beans>
BeanPostProcessor implementation class:
package com.wxw.processor.initialize; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; public class WxwBeanPostProcessor implements BeanPostProcessor { public WxwBeanPostProcessor(){ System.out.println("Call[ BeanPostProcessor]Construction method!!!"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("Call[ BeanPostProcessor]Yes[ Before]method!!!"); return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("Call[ BeanPostProcessor]Yes[ After]method!!!"); return bean; } }
Test class:
package com.wxw.test; import com.wxw.pojo.UserBean; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestClass { @Test public void test1(){ System.out.println("=====================IoC Container initialization begin========================="); ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml"); System.out.println("=====================IoC Container initialization end========================="); UserBean userBean = (UserBean) applicationContext.getBean("userBean"); System.out.println(userBean); } }
Operation results:
=====================IoC Container initialization begin========================= Call[ BeanFactoryPostProcessor]Construction method!!! Call[ BeanFactoryPostProcessor]Class postProcessBeanFactory method!!! Call[ InstantiationAwareBeanPostProcessor]Construction method!!! Call[ BeanPostProcessor]Construction method!!! =====================IoC Container initialization end========================= Call[ InstantiationAwareBeanPostProcessor]of Before method!!! Call[ UserBean]Construction method of!!! Call[ InstantiationAwareBeanPostProcessor]of After method!!! Call[ InstantiationAwareBeanPostProcessor]of postProcessProperties method!!! Call[ UserBean]Yes[ setName]method!!! Call[ UserBean]Yes[ setAge]method!!! Call[ BeanFactoryAware]Yes[ setBeanFactory]method!!! Call[ BeanPostProcessor]Yes[ Before]method!!! [InitializingBean]Yes[ init]Method execution!!! [init-method]Configured[ init]Method execution!!! Call[ BeanPostProcessor]Yes[ After]method!!! UserBean{name='Wxw', age=28}
4.2 sequence diagram
5. Bean destruction phase
When the Bean is destroyed, the destroy method of DisposableBean interface and the destroy method configured in xml will be executed.
5.1 code demonstration
UserBean class:
package com.wxw.pojo; import lombok.Data; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; import org.springframework.context.ApplicationContext; import org.springframework.context.ApplicationContextAware; @Data public class UserBean implements InitializingBean, BeanFactoryAware, ApplicationContextAware, DisposableBean { private String name; private Integer age; private BeanFactory beanFactory; private ApplicationContext applicationContext; @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { System.out.println("Call[ ApplicationContextAware]Yes[ setApplicationContext]method!!!"); this.applicationContext = applicationContext; } public UserBean() { System.out.println("Call[ UserBean]Construction method of!!!"); } public UserBean(String name, Integer age) { this.name = name; this.age = age; } public void setName(String name) { System.out.println("Call[ UserBean]Yes[ setName]method!!!"); this.name = name; } public void setAge(Integer age) { System.out.println("Call[ UserBean]Yes[ setAge]method!!!"); this.age = age; } @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { System.out.println("Call[ BeanFactoryAware]Yes[ setBeanFactory]method!!!"); this.beanFactory = beanFactory; } @Override public String toString() { return "UserBean{" + "name='" + name + '\'' + ", age=" + age + '}'; } @Override public void afterPropertiesSet() throws Exception { System.out.println("[InitializingBean]Yes[ init]Method execution!!!"); } public void init(){ System.out.println("[init-method]Configured[ init]Method execution!!!"); } @Override public void destroy() throws Exception { System.out.println("[DisposableBean]Yes[ destroy]Method execution"); } public void beanDestroy(){ System.out.println("[destroy-method]Configured[ beanDestroy]Method execution!!!"); } }
spring-config.xml
<?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"> <bean id="userBean" class="com.wxw.pojo.UserBean" lazy-init="true" init-method="init" destroy-method="beanDestroy" scope="singleton"> <property name="name" value="Wxw"/> <property name="age" value="18"/> </bean> <bean id="wxwBeanFactoryPostProcessor" class="com.wxw.processor.ioc.WxwBeanFactoryPostProcessor"></bean> <bean id="wxwInstantiationAwareBeanPostProcessor" class="com.wxw.processor.instantiation.WxwInstantiationAwareBeanPostProcessor"></bean> <bean id="wxwBeanPostProcessor" class="com.wxw.processor.initialize.WxwBeanPostProcessor"></bean> </beans>
Test class:
package com.wxw.test; import com.wxw.pojo.UserBean; import org.junit.Test; import org.springframework.context.support.ClassPathXmlApplicationContext; public class TestClass { @Test public void test1(){ System.out.println("=====================IoC Container initialization begin========================="); ClassPathXmlApplicationContext applicationContext = new ClassPathXmlApplicationContext("spring-config.xml"); System.out.println("=====================IoC Container initialization end========================="); UserBean userBean = (UserBean) applicationContext.getBean("userBean"); System.out.println(userBean); System.out.println("=====================IoC Container destruction begin========================="); applicationContext.close(); System.out.println("=====================IoC Container destruction end========================="); } }
Execution results:
=====================IoC Container initialization begin========================= Call[ BeanFactoryPostProcessor]Construction method!!! Call[ BeanFactoryPostProcessor]Class postProcessBeanFactory method!!! Call[ InstantiationAwareBeanPostProcessor]Construction method!!! Call[ BeanPostProcessor]Construction method!!! =====================IoC Container initialization end========================= Call[ InstantiationAwareBeanPostProcessor]of Before method!!! Call[ UserBean]Construction method of!!! Call[ InstantiationAwareBeanPostProcessor]of After method!!! Call[ InstantiationAwareBeanPostProcessor]of postProcessProperties method!!! Call[ UserBean]Yes[ setName]method!!! Call[ UserBean]Yes[ setAge]method!!! Call[ BeanFactoryAware]Yes[ setBeanFactory]method!!! Call[ ApplicationContextAware]Yes[ setApplicationContext]method!!! Call[ BeanPostProcessor]Yes[ Before]method!!! [InitializingBean]Yes[ init]Method execution!!! [init-method]Configured[ init]Method execution!!! Call[ BeanPostProcessor]Yes[ After]method!!! UserBean{name='Wxw', age=28} =====================IoC Container destruction begin========================= [DisposableBean]Yes[ destroy]Method execution [destroy-method]Configured[ beanDestroy]Method execution!!! =====================IoC Container destruction end========================= The process has ended with exit code 0