SpringBoot bean的常用扩展点
了解Spring这些扩展点,有助于我们编写更优雅的代码。扩展点的具体应用实践,我们可以多看优秀的源码借鉴思路。
扩展点顺序
- 【1】BeanFactoryPostProcessor postProcessBeanFactory. 【BeanFactoryPostProcessor beanFactory】
- 【2】InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation beanName:chat. 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】前。所有bean生效】
- 【3】Chat construct. 【bean 无参构造函数调用,实例化】
- 【4】InstantiationAwareBeanPostProcessor postProcessAfterInstantiation beanName:chat. 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】后】。所有bean生效
- 【5】BeanNameAware setBeanName, name: chat. 【实现 BeanNameAware接口】
- 【6】BeanFactoryAware setBeanFactory. 【实现 BeanFactoryAware 接口,传入bean容器】
- 【7】ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口,其继承自BeanFactory】
- 【8】BeanPostProcessor postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】
- 【9】Chat PostConstruct. 【init方法 @PostConstruct注解,初始化bean】
- 【10】Chat afterPropertiesSet. 【bean 实现InitializingBean接口,初始化bean】
- 【11】BeanPostProcessor postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】
- 【12】Chat PreDestroy. 【bean 销毁前调用】
- 【13】Chat destroy.【bean 销毁时调用】
代码
bean 举例
@Service
public class Chat implements InitializingBean, BeanNameAware, BeanFactoryAware, ApplicationContextAware, DisposableBean {
private static ApplicationContext appContext;
public Chat() {
System.out.println("【3】Chat construct. 【bean 无参构造函数调用,实例化】");
}
@PostConstruct
public void init() {
System.out.println("【9】Chat PostConstruct. 【init方法 @PostConstruct注解,初始化bean】");
}
@Override
public void afterPropertiesSet() throws Exception {
System.out.println("【10】Chat afterPropertiesSet. 【bean 实现InitializingBean接口,初始化bean】");
}
public void say() {
System.out.println("say something");
}
/**
* 单个bean 生效
*/
@Override
public void setBeanName(String name) {
System.out.println("【5】BeanNameAware setBeanName, name: " + name + ". 【实现 BeanNameAware接口】");
}
/**
* BeanFactoryAware 单个bean生效
* @throws BeansException
*/
@Override
public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
System.out.println("【6】BeanFactoryAware setBeanFactory. 【实现 BeanFactoryAware 接口,传入bean容器】");
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("【7】ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口,其继承自BeanFactory】");
appContext = applicationContext;
}
public <T> T getBean(String beanName, Class<T> requiredType) {
return appContext.getBean(beanName, requiredType);
}
@PreDestroy
public void preDestroy() {
System.out.println("【12】Chat PreDestroy. 【bean 销毁前调用】");
}
public void destroy() throws Exception {
System.out.println("【13】Chat destroy.【bean 销毁时调用】");
}
}
ApplicationContextAware 容器上下文 举例
@Component
public class AppContext implements ApplicationContextAware {
private static ApplicationContext appContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
System.out.println("ApplicationContextAware setApplicationContext. 【实现ApplicationContext接口】");
appContext = applicationContext;
}
public <T> T getBean(String beanName, Class<T> requiredType) {
return appContext.getBean(beanName, requiredType);
}
public <T> T getBean(Class<T> requiredType) {
return appContext.getBean(requiredType);
}
}
InstantiationAwareBeanPostProcessor 实例化前后 举例
@Component
public class InstantiationBeanPostProcessor implements InstantiationAwareBeanPostProcessor {
/**
* bean 实例化(new obj)之前调用
*/
public Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName) throws BeansException {
if ("chat".equals(beanName)) {
System.out.println("【2】InstantiationAwareBeanPostProcessor postProcessBeforeInstantiation beanName:" + beanName + ". 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】前。所有bean生效】");
}
return null;
}
/**
* bean 实例化(new obj)之后调用
*/
public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
if ("chat".equals(beanName)) {
System.out.println("【4】InstantiationAwareBeanPostProcessor postProcessAfterInstantiation beanName:" + beanName + ". 【实现 InstantiationAwareBeanPostProcessor接口 【实例化,非初始化】后】。所有bean生效");
}
return true;
}
/**
* 所有bean 都可生效
* InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor
* 初始化bean前调用,bean放到spring上下文之前
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【8】BeanPostProcessor postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】");
}
return bean;
}
/**
* 所有bean 都可生效
* InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor
* 初始化bean后调用,bean放到spring上下文之后
*/
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【11】BeanPostProcessor postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】");
}
return bean;
}
}
BeanFactoryPostProcessor 容器 举例
@Component
public class BeanFactoryPostProcess implements BeanFactoryPostProcessor {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
System.out.println("【1】BeanFactoryPostProcessor postProcessBeanFactory. 【BeanFactoryPostProcessor beanFactory】");
}
}
BeanPostProcessor bean初始化前后 举例
前边的InstantiationAwareBeanPostProcessor 继承自 BeanPostProcessor,也会继承内部这两个方法。
@Component
public class BeanPostProcess implements BeanPostProcessor {
/**
* 所有bean 都可生效
*/
public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【8】BeanPostProcessor postProcessBeforeInitialization. 【BeanPostProcessor 初始化前调用。所有bean 都可生效】");
}
return bean;
}
public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
if (beanName.equals("chat")) {
System.out.println("【11】BeanPostProcessor postProcessAfterInitialization. 【BeanPostProcessor 初始化后调用。所有bean 都可生效】");
}
return bean;
}
}
总结
bean的生命周期和SpringBoot开发中常用扩展点。
- bean整个容器、上下文的构造。
- 各个bean的实例化前后、初始化前后,可干预的扩展点。