Spring - IoC 容器之拓展点 BeanPostProcessor

概述

Spring - IoC 容器之 Bean 的生命周期 这篇文章中,我们了解了 SpringBean 的生命周期,我们知道底层是通过回调实现的。同时对于其他情况的回调,Spring 官方文档 中有介绍,BeanPostProcessor 接口中定义了回调方法,我们可以实现这些方法来提供自己的实例化逻辑、依赖处理逻辑等。如果我们想要在 Spring IoC 容器 完成 Bean实例化配置初始化 之后实现一些自定义的逻辑,可以定义一个或多个自定义的 BeanPostProcessor 实现。

同时,如果我们配置了多个 BeanPostProcessor 实例,我们可以通过实现 Ordered 接口设置 order 属性来控制这些实例的运行顺序。

public interface BeanPostProcessor {

	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
		return bean;
	}

}

举例

首先定义一个 BeanPostProcessor 的实现类:

@Component
public class MyBeanPostProcessor implements BeanPostProcessor {

    @Override
    public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessBeforeInitialization..." + beanName + ":" + bean);
        return bean;
    }

    @Override
    public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
        System.out.println("postProcessAfterInitialization..." + beanName + ":" + bean);
        return bean;
    }
}
@Component
public class Cat implements InitializingBean, DisposableBean {

    @Override
    public void destroy() throws Exception {
        System.out.println("cat destroy...");
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("cat afterPropertiesSet...");
    }
}

创建 IoC 容器后,输出结果:

// 配置类初始化前调用
postProcessBeforeInitialization...mainConfigOfLifeCycle:com.keke.config.MainConfigOfLifeCycle$$EnhancerBySpringCGLIB$$661f10cf@4b213651
// 配置类初始化之后调用
postProcessAfterInitialization...mainConfigOfLifeCycle:com.keke.config.MainConfigOfLifeCycle$$EnhancerBySpringCGLIB$$661f10cf@4b213651
// Bean 初始化调用之前
postProcessBeforeInitialization...com.keke.bean.Cat:com.keke.bean.Cat@4241e0f4
// Bean 初始化
cat afterPropertiesSet...
// Bean 初始化调用之后
postProcessAfterInitialization...com.keke.bean.Cat:com.keke.bean.Cat@4241e0f4
// 容器关闭,Bean 销毁
cat destroy...

原理

上面的 org.springframework.beans.factory.config.BeanPostProcessor 接口,定义了两个默认方法,postProcessBeforeInitialization 方法在 InitializingBean.afterPropertiesSet()自定义的 init 方法 等初始化方法之前执行,postProcessAfterInitialization 在之后执行。

ApplicationContext 会自动检测实现了 BeanPostProcessor 接口的实现类,并在 Bean 创建过程中调用这些 BeanPostProcessor,当然,这些实现了 BeanPostProcessor 接口的实现类需要作为 Bean 注册到 IoC 容器 中。

在这里插入图片描述

AbstractAutowireCapableBeanFactorydoCreateBean 方法中执行了创建 Bean 的过程:

在这里插入图片描述

在核心方法 initializeBean 方法中执行了初始化 Bean 的操作:

protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) {
	...

	Object wrappedBean = bean;
	if (mbd == null || !mbd.isSynthetic()) {
		// 执行所有 BeanPostProcessor 实现类的 postProcessBeforeInitialization 方法
		wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
	}

	try {
		// 调用初始化方法
		invokeInitMethods(beanName, wrappedBean, mbd);
	}
	catch (Throwable ex) {
		throw new BeanCreationException(
				(mbd != null ? mbd.getResourceDescription() : null),
				beanName, "Invocation of init method failed", ex);
	}
	if (mbd == null || !mbd.isSynthetic()) {
		// 执行所有 BeanPostProcessor 实现类的 postProcessAfterInitialization 方法
		wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
	}

	return wrappedBean;
}

总结

Spring 底层,大量使用了 BeanPostProcessor 来进行 Bean 的初始化前后的操作,我们查看 BeanPostProcessor 的常见实现类:

在这里插入图片描述

InitDestroyAnnotationBeanPostProcessor 就是用来处理 @PostConstruct@PreDestroy 注解的。AutowiredAnnotationBeanPostProcessor 是用来处理 @Autowired 注解的。

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值