Lifecycle Flowchart
We first pass a flow chart to make an overall understanding and understanding of the Bean life cycle.
If the container implements the interfaces involved in the flowchart, the program will follow the above process. It should be noted that these interfaces are not required to be implemented, and can be selected flexibly according to the needs of our own development. If the relevant interfaces are not implemented, the relevant steps in the flowchart will be omitted.
Classification of interface methods
The above flow chart involves calling a lot of methods. It may be difficult for us to understand and memorize directly. In fact, for such a large number of methods, we can sort and classify them according to their characteristics. The following provides a classification model for your reference. :
Classification type | Included methods |
---|---|
Bean's own methods | The methods configured by init-method and destroy-method in the configuration file, and the methods called by the bean object itself |
Bean-level lifecycle interface methods | Methods in interfaces such as BeanNameAware, BeanFactoryAware, InitializingBean, DiposableBean, etc. |
Container-level lifecycle interface methods | Post-processor implementation classes such as InstantiationAwareBeanPostProcessor, BeanPostProcessor and other overridden methods |
At this time, when we look back and look at the outline of these methods, the outlines of these methods are relatively clear. When remembering, we can understand the methods involved in sexual memory through the types of memory classifications.
programming practice
With the above theoretical analysis, let's verify our conclusions through programming practice, and by the way, further deepen our understanding of the entire life cycle.
Ready to work
Writing test beans
We first write a test bean to implement the relevant interfaces in the flowchart.
StudentBean.java
package com.yanxiao.cyclelife; import org.springframework.beans.BeansException; import org.springframework.beans.factory.BeanFactory; import org.springframework.beans.factory.BeanFactoryAware; import org.springframework.beans.factory.BeanNameAware; import org.springframework.beans.factory.DisposableBean; import org.springframework.beans.factory.InitializingBean; /** * Beans for testing life cycle * Created by yanxiao on 2016/8/1. */ public class StudentBean implements InitializingBean, DisposableBean, BeanNameAware, BeanFactoryAware { private String name; private int age; private String beanName;//The BeanNameAware interface is implemented, and Spring can inject BeanName into this property private BeanFactory beanFactory;//The BeanFactory interface is implemented, and Spring can inject the BeanFactory into this property public StudentBean(){ System.out.println("[Bean constructor] No-parameter constructor of student class"); } @Override public String toString() { return "StudentBean{" + "name='" + name + '\'' + ", age=" + age + ", beanName = '" + beanName +' \ '' + '}'; } public String getName() { return name; } public void setName(String name) { System.out.println("[set injection] inject the student's name attribute"); this.name = name; } public int getAge() { return age; } public void setAge(int age) { System.out.println("[set injection] inject the student's age attribute"); this.age = age; } /** * Initialization method written by yourself */ public void myInit(){ System.out.println("[init-method] Call the initialization method of the init-method attribute configuration"); } /** * Destruction method written by yourself */ public void myDestroy(){ System.out.println("[destroy-method] call the destroy method configured by the destroy-method attribute"); } /** * Methods of the BeanFactoryAware interface * @param beanFactory * @throws BeansException */ @Override public void setBeanFactory(BeanFactory beanFactory) throws BeansException { this.beanFactory = beanFactory; System.out.println("[BeanFactoryAware interface] Call the setBeanFactory method of BeanFactoryAware to get the beanFactory reference"); } /** * Methods of the BeanNameAware interface * @param name */ @Override public void setBeanName(String name) { this.beanName = name; System.out.println("[BeanNameAware interface] call the setBeanName method of BeanNameAware to get the name of the bean"); } /** * Method of InitializingBean interface * @throws Exception */ @Override public void afterPropertiesSet() throws Exception { System.out.println("[InitializingBean interface] call the afterPropertiesSet method of the InitializingBean interface"); } /** * Methods of the DisposableBean interface * @throws Exception */ @Override public void destroy() throws Exception { System.out.println("[DisposableBean interface] call the destroy method of DisposableBean interface"); } }The
myInit()
and for us to specify in the configuration file through the init-method and destroy-method properties.
Implement the BeanPostProcessor interface
We write an implementation class of the BeanPostProcessor interface: MyBeanPostProcessor.java
package com.yanxiao.cyclelife; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * Created by yanxiao on 2016/8/1. */ public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor(){ System.out.println("[BeanPostProcessor interface] calls the constructor of BeanPostProcessor"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("[BeanPostProcessor interface] calls the postProcessBeforeInitialization method, where the properties of "+beanName+" can be changed."); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("[BeanPostProcessor interface] calls the postProcessAfterInitialization method, where the properties of "+beanName+" can be changed."); return bean; } }
Implement the BeanPostProcessor interface
Write an implementation class MyBeanPostProcessor.java of the BeanPostProcessor interface
package com.yanxiao.cyclelife; import org.springframework.beans.BeansException; import org.springframework.beans.factory.config.BeanPostProcessor; /** * Created by yanxiao on 2016/8/1. */ public class MyBeanPostProcessor implements BeanPostProcessor { public MyBeanPostProcessor(){ System.out.println("[BeanPostProcessor interface] calls the constructor of BeanPostProcessor"); } @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("[BeanPostProcessor interface] calls the postProcessBeforeInitialization method, where the properties of "+beanName+" can be changed."); return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("[BeanPostProcessor interface] calls the postProcessAfterInitialization method, where the properties of "+beanName+" can be changed."); return bean; } }
Implement the InstantiationAwareBeanPostProcessor interface
Implement the InstantiationAwareBeanPostProcessor interface. For the convenience of programming, we directly test by inheriting an adapter class InstantiationAwareBeanPostProcessorAdapter already provided in Spring that implements this interface.
MyInstantiationAwareBeanPostProcessor.java
package com.yanxiao.cyclelife; import org.springframework.beans.BeansException; import org.springframework.beans.PropertyValues; import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessorAdapter; import java.beans.PropertyDescriptor; /** * In general, when we need to implement the InstantiationAwareBeanPostProcessor interface, we implement the class by inheriting the InstantiationAwareBeanPostProcessor interface in the Spring framework * InstantiationAwareBeanPostProcessorAdapter this adapter class to simplify our work to implement the interface * Created by yanxiao on 2016/8/1. */ public class MyInstantiationAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter { public MyInstantiationAwareBeanPostProcessor() { System.out.println("[InstantiationAwareBeanPostProcessor interface] call the InstantiationAwareBeanPostProcessor constructor"); } /** * Called before instantiating the bean */ @Override public Object postProcessBeforeInstantiation(Class beanClass, String beanName) throws BeansException { System.out.println("[InstantiationAwareBeanPostProcessor interface] call the postProcessBeforeInstantiation method of the InstantiationAwareBeanPostProcessor interface"); return null; } /** * Called after instantiating the bean */ @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("[InstantiationAwareBeanPostProcessor interface] call the postProcessAfterInitialization method of the InstantiationAwareBeanPostProcessor interface"); return bean; } /** * Called when a property is set */ @Override public PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName) throws BeansException { System.out.println("[InstantiationAwareBeanPostProcessor interface] call the postProcessPropertyValues method of the InstantiationAwareBeanPostProcessor interface"); return pvs; } }
BeanFactoryPostProcessor interface
We write an implementation class BeanFactoryPostProcessor.java of the BeanFactoryPostProcessor interface
package com.yanxiao.cyclelife; 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; /** * Created by yanxiao on 2016/8/1. */ public class MyBeanFactoryPostProcessor implements BeanFactoryPostProcessor { public MyBeanFactoryPostProcessor() { System.out.println("[BeanFactoryPostProcessor interface] call BeanFactoryPostProcessor to implement class construction method"); } /** * Rewrite the postProcessBeanFactory method of the BeanFactoryPostProcessor interface, which can be used to set the beanFactory */ @Override public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException { System.out.println("[BeanFactoryPostProcessor interface] calls the postProcessBeanFactory method of the BeanFactoryPostProcessor interface"); BeanDefinition beanDefinition = beanFactory.getBeanDefinition("studentBean"); beanDefinition.getPropertyValues().addPropertyValue("age", "21"); } }
Write the Spring configuration file beans.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" xmlns:p="http://www.springframework.org/schema/p" xmlns:aop="http://www.springframework.org/schema/aop" xmlns:tx="http://www.springframework.org/schema/tx" xsi:schemaLocation=" http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.2.xsd"> <!--Configure Bean's post-processor--> <bean id="beanPostProcessor" class="com.yanxiao.cyclelife.MyBeanPostProcessor"> </bean> <!--配置instantiationAwareBeanPostProcessor--> <bean id="instantiationAwareBeanPostProcessor" class="com.yanxiao.cyclelife.MyInstantiationAwareBeanPostProcessor"> </bean> <!--Configure the post processor of BeanFactory--> <bean id="beanFactoryPostProcessor" class="com.yanxiao.cyclelife.MyBeanFactoryPostProcessor"> </bean> <bean id="studentBean" class="com.yanxiao.cyclelife.StudentBean" init-method="myInit" destroy-method="myDestroy" scope="singleton"> <property name="name" value="yanxiao"></property> <property name="age" value="21"></property> </bean> </beans>
carry out testing
Through the above preparations, we have written the relevant classes and test files, and now we will verify our results through the test code.
package com.yanxiao.cyclelife; import org.springframework.context.ApplicationContext; import org.springframework.context.support.ClassPathXmlApplicationContext; /** * Created by yanxiao on 2016/8/1. */ public class TestCyclelife { public static void main(String[] args){ System.out.println("---------------[Initialization container]---------------"); ApplicationContext context = new ClassPathXmlApplicationContext("META-INF/beans1.xml"); System.out.println("-------------------[Container initialization succeeded]-------------------" ); //Get studentBean and display its information StudentBean studentBean = context.getBean("studentBean",StudentBean.class); System.out.println(studentBean); System.out.println("--------------------[Destroy the container]------------------- ---"); ((ClassPathXmlApplicationContext)context).registerShutdownHook(); } }