Spring IOC 初始化刷新流程六:registerBeanPostProcessors(beanFactory)
2021-03-11 21:29
标签:common finally 调用 注册 一个 不能 factory const processor Spring IOC 初始化刷新流程:https://www.cnblogs.com/jhxxb/p/13609289.html 这一步主要是实例化和注册 beanFactory 中实现了 BeanPostProcessor 接口的 Bean。 什么是 BeanPostProcessor 先看 BeanFactory 的 getBeanPostProcessors() 返回的是什么 再看容器启动时,用 BeanFactory#addBeanPostProcessor 添加进去的 Bean 后置处理器 具体源码 至此,这一步完成。Spring 从所有的 @Bean 定义中抽取出来了 BeanPostProcessor,然后都注册进 beanPostProcessors,等待后面的的顺序调用 Spring IOC 初始化刷新流程六:registerBeanPostProcessors(beanFactory) 标签:common finally 调用 注册 一个 不能 factory const processor 原文地址:https://www.cnblogs.com/jhxxb/p/13957928.html/**
* 接口中两个方法不能返回 null,如果返回 null 在后续的初始化方法中将报空指针异常,或者通过 getBean() 方法获取不到 bena 实例对象,
* 因为后置处理器从 Spring IOC 容器中取出 bean 实例对象没有再次放回 IOC 容器中。
*
* BeanFactory 和 ApplicationContext 注册 Bean 的后置处理器不通点:
* ApplicationContext 直接使用 @Bean 注解,就能向容器注册一个后置处理器,它注册 Bean 的时候,会先检测是否实现了 BeanPostProcessor 接口,
* 并自动把它们注册为后置处理器。所以在使用 ApplicationContext 注册一个后置处理器和注册一个普通的 Bean 是没有区别的。
* BeanFactory 必须显示的调用:void addBeanPostProcessor(BeanPostProcessor beanPostProcessor 才能注册进去。
*
* Spring 可以注册多个 Bean 的后置处理器,是按照注册的顺序进行调用的。若想定制顺序,可以标注 @Order 或者实现 Order 接口。
*/
public interface BeanPostProcessor {
/**
* 在 Bean 实例化/依赖注入完毕之后,自定义初始化方法执行之前调用
* 自定义初始化方法:init-method、@PostConstruct、实现 InitailztingBean 接口等
*
* @param bean 这个 Bean 实例
* @param beanName bean 名称*/
@Nullable
default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
/**
* 在上面基础上,初始化方法执行之后调用
*/
@Nullable
default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException {
return bean;
}
}
方法源码
public abstract class AbstractBeanFactory extends FactoryBeanRegistrySupport implements ConfigurableBeanFactory {
/** BeanPostProcessors to apply. */
private final List
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
// Configure the bean factory with context callbacks.
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 这里
// Register early post-processor for detecting inner beans as ApplicationListeners.
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this)); // 这里
// Detect a LoadTimeWeaver and prepare for weaving, if found.
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory)); // 这里
public abstract class AbstractRefreshableWebApplicationContext extends AbstractRefreshableConfigApplicationContext implements ConfigurableWebApplicationContext, ThemeSource {
@Override
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext, this.servletConfig)); // 这里
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
@Override
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException("postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
// BeanDefinitionRegistryPostProcessor hook apparently not supported...
// Simply call processConfigurationClasses lazily at this point then.
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory)); // 这里
}
private static class ImportAwareBeanPostProcessor extends InstantiationAwareBeanPostProcessorAdapter {
public abstract class AbstractApplicationContext extends DefaultResourceLoader implements ConfigurableApplicationContext {
protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 委托给 PostProcessorRegistrationDelegate 去做
PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this);
}
final class PostProcessorRegistrationDelegate {
public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) {
// 从所有 Bean 定义中提取出 BeanPostProcessor 类型的 Bean,注意和 getBeanPostProcessors 的结果区分开来,虽然都是 BeanPostProcessor
// 最初的 6 个 bean,有 2 个是 BeanPostProcessor:
// AutowiredAnnotationBeanPostProcessor、CommonAnnotationBeanPostProcessor
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
// Register BeanPostProcessorChecker that logs an info message when
// a bean is created during BeanPostProcessor instantiation, i.e. when
// a bean is not eligible for getting processed by all BeanPostProcessors.
// 向 beanFactory 又 add 了一个 BeanPostProcessorChecker,且总数设置为了 getBeanPostProcessorCount 和 addBeanPostProcessor 的总和(+1表示自己)
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
// beanProcessorTargetCount 表示的是处理器的总数,总数(包含两个位置的,用于后面的校验)
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
// Separate between BeanPostProcessors that implement PriorityOrdered,
// Ordered, and the rest.
// 先按优先级,归类 BeanPostProcessor
List
上一篇:JAVAWEB核心
下一篇:数组静态初始化和动态初始化
文章标题:Spring IOC 初始化刷新流程六:registerBeanPostProcessors(beanFactory)
文章链接:http://soscw.com/index.php/essay/63374.html