The so-called life cycle of Spring Bean refers to the process of Bean from creation to initialization to destruction. This process is managed by the IOC container. A complete Bean life cycle can refer to the Spring Bean life cycle . Here we mainly record some details related to the Bean life cycle.
Bean initialization and destruction
Throughout the life cycle, we can customize the initialization and destruction hook functions of the Bean. When the Bean's life cycle reaches the corresponding stage, Spring will call our custom Bean initialization and destruction methods. There are many ways to customize Bean initialization and destruction methods, which are introduced one by one below.
@Bean
The previous section introduced that you can @Bean
register the Bean through annotations in the configuration class, and we can also use it to specify the initialization and methods of the Bean.
To demonstrate, we create a new Spring Boot project, and then create a User
class:
public class User {
public User() {
System.out.println("调用无参构造器创建User");
}
public void init() {
System.out.println("初始化User");
}
public void destory() {
System.out.println("销毁User");
}
}
Then register the component in the configuration class and specify the initialization and destruction methods:
@Configuration
public class WebConfig {
@Bean(initMethod = "init", destroyMethod = "destory")
public User user() {
return new User();
}
}
Wherein initMethod = "init"
and destroyMethod = "destory"
with the User class init
, destory
a corresponding method.
Test in the Spring Boot entry class:
// 返回 IOC 容器,使用注解配置,传入配置类
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
User user = context.getBean(User.class);
// 关闭 IOC 容器
context.close();
Start the project and observe the console output:
From the above output, we can see that before the container is started, the parameterless constructor of the object is called to create the object, then the initialization method is called, and the destruction method is called when the container is closed.
The above situation is for singleton, what if the component is in multiple instances? We change the above component registration configuration to multiple cases, then start the project again, and observe the console output:
The console output is consistent with what we discussed in the previous section, that is, in the multi-case mode, the IOC container will not create an object when it is started, but will call the method to create the object every time it gets it, and the object is created. Then call the initialization method. But after the container is closed, Spring does not call the corresponding destruction method. This is because in the multi-case mode, the container does not manage this component (only responsible for creating this component when you need it), so the container does not The corresponding destruction method will not be called.
InitializingBean&DisposableBean
In addition to specifying the initialization and destruction methods in the above way, Spring also provides us with the interface corresponding to initialization and destruction:
-
InitializingBean
The interface contains aafterPropertiesSet
method, we can implement the interface, and then write initialization logic in this method. -
DisposableBean
The interface contains adestory
method, we can implement the interface, and then write the destruction logic in this method.
Create a new class, name it Bird
, and implement these two interfaces:
public class Bird implements InitializingBean, DisposableBean {
public Bird() {
System.out.println("调用无参构造器创建Bird");
}
@Override
public void destroy() {
System.out.println("销毁Bird");
}
@Override
public void afterPropertiesSet() {
System.out.println("初始化Bird");
}
}
Register this component in the configuration class:
@Bean
public Bird bird() {
return new Bird();
}
Test a wave:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
System.out.println("容器创建完毕");
context.close();
Start the project and observe the console output:
@PostConstruct&@PreDestroy
In addition to the above two ways of specifying initialization and destruction methods, we can also use @PostConstruct
and @PreDestroy
annotation modification methods to specify the corresponding initialization and destruction methods.
Create a new class named Fish:
public class Fish {
public Fish() {
System.out.println("调用无参构造器创建Fish");
}
@PostConstruct
public void init() {
System.out.println("初始化Fish");
}
@PreDestroy
public void destory() {
System.out.println("销毁Fish");
}
}
Register this component in the configuration class:
@Bean
public Fish fish(){
return new Fish();
}
Test a wave:
AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(WebConfig.class);
System.out.println("容器创建完毕");
context.close();
Start the project and observe the console output:
The effect is the same as the above two methods.
These two annotations are not provided by Spring, but provided by the JSR250 specification.
BeanPostProcessor
Spring provides an BeanPostProcessor
interface, commonly known as the Bean post-notification processor , which provides two methods postProcessBeforeInitialization
and postProcessAfterInitialization
. Which is postProcessBeforeInitialization
executed before postProcessAfterInitialization
the initialization method of the component is called, and executed after the initialization method of the component is called. They both contain two input parameters:
-
bean: current component object;
-
beanName: The name of the current component in the container.
Both methods return an Object type, we can directly return the current component object, or return after packaging.
Let's define BeanPostProcessor
the implementation class of an interface MyBeanPostProcessor
:
public class MyBeanPostProcessor implements BeanPostProcessor {
@Override
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " 初始化之前调用");
return bean;
}
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
System.out.println(beanName + " 初始化之后调用");
return bean;
}
}
Register the component in the configuration class:
@Bean
public MyBeanPostProcessor myBeanPostProcessor () {
return new MyBeanPostProcessor();
}
Start the project again and observe the console output:
As you can see, BeanPostProcessor is effective for all components in the IOC container.