The life cycle of Spring beans
The life cycle of the Bean
1. Initialize the Bean
The container is instantiated by taking information from the BeanDefinition, which is a simple instantiation step without dependency injection.
The instantiated object is wrapped in a BeanWrapper object, which provides an interface to set the properties of the object, avoiding the need for reflection to inject properties.
2. Set object properties (dependency injection)
The instantiated Bean is still in its native state, and Spring then does dependency injection based on the information in BeanDefinition and through the interface provided by BeanWrapper to set properties.
3. Inject Aware interface
Spring detects whether the object implements the xxxAware interface and injects the associated xxxAware instance into the bean.
BeanNameAware
: To obtain the Bean ID through the reference of the Bean, which is rarely used in general services.BeanFactoryAware
: Get Spring BeanFactory containers, such as publish events, etc.ApplicationContextAwaer
: Get the Spring ApplicationContext container;
4. BeanPostProcessor preprocessing
If Spring implements the BeanPostProcessor interface, pring will invoke them postProcessBeforeInitialization (Object beans, String beanName) (initialization) method, The purpose is to enhance the Bean instance after it is created successfully, such as modifying the Bean to add a certain function.
5. InitializingBean interface
The InitializingBean interface has only one function: AfterPropertiesSet (), which adds our own custom logic before the bean is formally constructed. Unlike the pre-processing, this function does not have a bean object as it cannot process the bean object itself, only some additional logic can be added.
6. The init method statement
This works as the InitializingBean interface.
7. BeanPostProcessor postprocessing
If Spring implements the BeanPostProcessor interface, pring will invoke them postProcessAfterInitialization (Object beans, String beanName) (initialization) method, effect and 4, Except that 6 is executed before the Bean is initialized, and this is executed after the Bean is initialized, at a different time.
8. The Bean initialization is complete
After the above work, the Bean will reside in the application context for use by the application until the application context is destroyed.
9. DispostbleBean interface
The DispostbleBean interface has only one function: destroy(), which executes the logic in this function before the bean is destroyed.
10. Destroy – method statement
Works with DispostbleBean interface.
code
The Person class implements the interfaces of BeanNameAware, BeanFactoryAware, ApplicationContextAwaer, InitializingBean and DispostbleBean.
package tech.mervyn.demo.entity;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
public class Person implements BeanNameAware.BeanFactoryAware.ApplicationContextAware.InitializingBean.DisposableBean {
private String name;
public Person(a) {
System.out.println("Call the default constructor to instantiate the object...");
}
public void setName(String name) {
System.out.println("Call Setter method to set property...");
this.name = name;
}
public String getName(a) {
return name;
}
@Override
public String toString(a) {
return "Person{" +
"name='" + name + '\' ' +
'} ';
}
@Override
public void setBeanName(String name) {
System.out.println("Get beanName ->" + name);
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("Get BeanFactory ->" + beanFactory.hashCode());
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("Get applicationContext ->" + applicationContext.hashCode());
}
@Override
public void afterPropertiesSet(a) throws Exception {
System.out.println("Execute InitializingBean logic...");
}
public void initMethod(a) {
System.out.println("Execute init-method declaration logic...");
}
@Override
public void destroy(a) throws Exception {
System.out.println("Execute DisposableBean logic...");
}
public void destroyMethod(a) {
System.out.println("Execute destroy-method declaration logic..."); }}Copy the code
Custom MyBeanPostProcessor BeanPostProcessor class hierarchy and implement postProcessBeforeInitialization (Object bean, String beanName) and postProcessAfterInitialization (Object beans, String beanName) method.
package tech.mervyn.demo.processor;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.BeanPostProcessor;
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor preprocessing," + beanName + "- >" + bean);
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println("BeanPostProcessor post-processing," + beanName + "- >" + bean);
returnbean; }}Copy the code
The configuration class
package tech.mervyn.demo.config;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import tech.mervyn.demo.entity.Person;
import tech.mervyn.demo.processor.MyBeanPostProcessor;
@Configuration
public class AppConfig {
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
public Person person(a) {
Person person = new Person();
person.setName("Mervyn");
return person;
}
@Bean
public MyBeanPostProcessor myBeanPostProcessor(a) {
return newMyBeanPostProcessor(); }}Copy the code
perform
package tech.mervyn.demo;
import org.junit.jupiter.api.Test;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import tech.mervyn.demo.config.AppConfig;
public class LiftCycleTests {
@Test
void liftCycle(a) {
AnnotationConfigApplicationContext context = newAnnotationConfigApplicationContext(AppConfig.class); context.registerShutdownHook(); }}Copy the code
Output, which removes some useless logs:
22:29:54. 047. [the main] the DEBUG org. Springframework. Beans. Factory. Support. DefaultListableBeanFactory - Creating Shared Instance of singleton bean 'appConfig' 22:29:54.052 [main] INFO org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker - Bean 'appConfig' of type [tech.mervyn.demo.config.AppConfig$$EnhancerBySpringCGLIB$$b60c41a9] is not eligible for getting processed by all BeanPostProcessors (for example: Not eligible for auto-proxying) 22:29:54.072 [main] DEBUG org.springframework.beans.factory.support.DefaultListableBeanFactory - Creating shared instance of singleton bean 'person' calls the default constructor to instantiate the object... Call Setter methods to set properties... Obtain beanName -> Person -> 1390913202 obtain applicationContext -> 1297836716 BeanPostProcessor Person -> person {name='Mervyn'} execute InitializingBean logic... Execute init-method to declare logic... Person -> person {name='Mervyn'} Execute DisposableBean logic... Execute the destroy-method declaration logic...Copy the code
Notice this line in the log: org.springframework.context.support.PostProcessorRegistrationDelegate$BeanPostProcessorChecker – Bean ‘appConfig’ of type [tech.mervyn.demo.config.AppConfig$$EnhancerBySpringCGLIB$$b60c41a9] is not eligible for getting processed by all BeanPostProcessors (for example: not eligible for auto-proxying). This is generated when BeanPostProcessor starts up and causes error to dependent beans.