一,概述
bean的生命周期主要有如下几个步骤:
- 实例化阶段Instantiation;
- 填充属性;
- 初始化阶段Initialization;
- 通过IOC容器使用bean;
- 销毁阶段destroy()
调用时机:
-> refresh()
-> finishBeanFactoryInitialization(beanFactory)
-> beanFactory.preInstantiateSingletons()
-> getBean()
-> doGetBean()
-> createBean()
-> doCreateBean()
二,扩展点
扩展点可分为影响多个Bean和影响单个Bean:
- 影响多个 bean
- InstantiationAwareBeanPostProcessor
- BeanPostProcessor
- 影响单个Bean
- Aware
- @PostConstruct
- InitializingBean#afterPropertiesSet
- init-method
- @PreDestroy
- DisposableBean#destroy
2.1,实例化阶段扩展点
2.1.1,InstantiationAwareBeanPostProcessor
作用在实例化过程前后的后置处理器,是BeanPostProcessor的子接口
实例化前执行:postProcessBeforeInstantiation
实例化后执行:postProcessAfterInstantiation
2.2,初始化阶段扩展点
2.2.1,Aware
作用:让我们能够拿到 Spring容器中的一些资源。基本都能够见名知意,Aware之前的名字就是可以拿到什么资源,例如 BeanNameAware 可以拿到BeanName,以此类推。
调用时机:所有的 Aware 方法都是在初始化阶段之前调用的!
Aware系列接口的共性:
- 都以 Aware 结尾;
- 都是 Aware 接口的子接口;
- 接口内均定义了一个 set 方法;
Aware分类(按顺序执行):
- Aware Group1
- BeanNameAware
- BeanClassLoaderAware
- BeanFactoryAware
- Aware Group2
- EnvironmentAware
- EmbeddedValueResolverAware
- ApplicationContextAware(ResourceLoaderAware\ApplicationEventPublisherAware\MessageSourceAware)
2.2.2,BeanPostProcessor
作用在初始化过程前后的后置处理器
初始化前执行:postProcessBeforeInitialization
初始化后执行:postProcessAfterInitialization
2.2.3,@PostConstruct
@PostConstruct 是 Java 的注解, 用来修饰方法,标记在项目启动的时候执行这个方法,一般用来执行某些初始化操作比如全局配置。@PostConstruct 注解的方法会在构造函数之后执行,Servlet 的init()方法之前执行。
@PostConstruct 和 @PreDestroy 是两个作用于Servlet生命周期的注解, 被这两个注解修饰的方法可以保证在整个 Servlet 生命周期只被执行一次,即使 Web 容器在其内部中多次实例化该方法所在的 bean。
2.2.4,InitializingBean#afterPropertiesSet
InitializingBean 是 Spring 提供的拓展性接口,InitializingBean 接口为 bean 提供了属性初始化后的处理方法,它只有一个 afterPropertiesSet 方法。
2.2.5,init-method
初始化bean的时候执行,可以针对某个具体的bean进行配置。
实现 InitializingBean 或配置 init-method 均可参与bean初始化流程。
实现一:xml 配置
<bean id="TestBean" class="xxx.TestBean" init-method="init"/>
实现二:@Bean 注解配置
@Bean(initMethod = "initMethod", destroyMethod = "destroyMethod")
2.3,销毁阶段扩展点
允许容器销毁该 bean 时获得一次回调,在 Servlet 的 destroy() 方法之前执行,一般用来释放 bean 所持有的资源。
实现方式一:在方法上添加 @PreDestroy 注解
实现方式二:实现 DisposableBean#destroy
2.4,执行时机
→ 构造方法
→ postProcessBeforeInstantiation
→ postProcessAfterInstantiation
→ Aware
→ postProcessBeforeInitialization
→ @PostConstruct
→ InitializingBean#afterPropertiesSet
→ init-method
→ postProcessAfterInitialization
→ @PreDestroy
→ DisposableBean#destroy
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.*;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.EmbeddedValueResolverAware;
import org.springframework.context.EnvironmentAware;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.util.StringValueResolver;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@Component
public class MyInitializingBean implements InitializingBean, BeanNameAware,
BeanClassLoaderAware, BeanFactoryAware,
EnvironmentAware, EmbeddedValueResolverAware,
ApplicationContextAware,DisposableBean {
public MyInitializingBean() {
System.out.println("构造方法执行...");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("afterPropertiesSet 方法执行...");
}
@PostConstruct
public void postConstruct() {
System.out.println("@PostConstruct 方法执行...");
}
@PreDestroy
public void PreDestroy(){
System.out.println("@PreDestroy 方法执行...");
}
@Override
public void setBeanName(String s) {
System.out.println("setBeanName 方法执行...");
}
@Override
public void setBeanClassLoader(ClassLoader classLoader) {
System.out.println("setBeanClassLoader 方法执行...");
}
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("setBeanFactory 方法执行...");
}
@Override
public void setEmbeddedValueResolver(StringValueResolver stringValueResolver) {
System.out.println("setEmbeddedValueResolver 方法执行...");
}
@Override
public void setEnvironment(Environment environment) {
System.out.println("setEnvironment 方法执行...");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("setApplicationContext 方法执行...");
}
@Override
public void destroy() throws Exception {
System.out.println("DisposableBean#destroy 方法执行...");
}
}
执行结果:
评论区