当前位置 : 主页 > 编程语言 > java >

Spring5 IOC容器解析——registerBeanPostProcessors(beanFactory)方法分析

来源:互联网 收集:自由互联 发布时间:2023-02-04
前言 invokeBeanFactoryPostProcessors 方法主要用于处理 BeanFactoryPostProcessor 接口,而 registerBeanPostProcessors 方法主要用于处理 BeanPostProcessor 接口。BeanFactoryPostProcessor 和 BeanPostProcessor,相信大家

前言

invokeBeanFactoryPostProcessors 方法主要用于处理 BeanFactoryPostProcessor 接口,而 registerBeanPostProcessors 方法主要用于处理 BeanPostProcessor 接口。BeanFactoryPostProcessor 和 BeanPostProcessor,相信大家很容易从命名看出来这两个接口“长得很像”。BeanFactoryPostProcessor 是针对 BeanFactory 的扩展,主要用在 bean 实例化之前,读取 bean 的定义,并可以修改它。BeanPostProcessor 是针对 bean 的扩展,主要用在 bean 实例化之后,执行初始化方法前后,允许开发者对 bean 实例进行修改。

概述

本方法会注册所有的 BeanPostProcessor,将所有实现了 BeanPostProcessor 接口的类加载到 BeanFactory 中。

 

BeanPostProcessor 接口是 Spring 初始化 bean 时对外暴露的扩展点,Spring IoC 容器允许 BeanPostProcessor 在容器初始化 bean 的前后,添加自己的逻辑处理。在 registerBeanPostProcessors 方法只是注册到 BeanFactory 中,具体调用是在 bean 初始化的时候。

 

具体的:在所有 bean 实例化时,执行初始化方法前会调用所有 BeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用所有 BeanPostProcessor 的 postProcessAfterInitialization 方法。

正文

首先我们回到 AbstractApplicationContext.refresh() 方法,找到代码:registerBeanPostProcessors(beanFactory),单击该行代码跳转到具体的实现。

/** * 加载或刷新一个持久化的配置,可能是XML文件、属性文件或关系数据库模式。 * 由于这是一种启动方法,如果失败,应该销毁已经创建的单例,以避免悬空资源。 * 换句话说,在调用该方法之后,要么全部实例化,要么完全不实例化。 * @throws BeansException 如果bean工厂无法初始化,则抛出 BeansException 异常 * @throws IllegalStateException 如果已经初始化且不支持多次刷新,则会抛出 IllegalStateException 异常 */ @Override public void refresh() throws BeansException, IllegalStateException { // 给容器refresh加锁,避免容器处在refresh阶段时,容器进行了初始化或者销毁的操作 synchronized (this.startupShutdownMonitor) { // Prepare this context for refreshing. // 调用容器准备刷新的方法,获取容器的当时时间,同时给容器设置同步标识,具体方法 prepareRefresh(); // Tell the subclass to refresh the internal bean factory. //告诉子类启动refreshBeanFactory()方法,Bean定义资源文件的载入从 //子类的refreshBeanFactory()方法启动,里面有抽象方法 //针对xml配置,最终创建内部容器,该容器负责 Bean 的创建与管理,此步会进行BeanDefinition的注册 ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // Prepare the bean factory for use in this context. // 注册一些容器中需要的系统Bean.例如classloader,beanfactoryPostProcessor等 prepareBeanFactory(beanFactory); try { // Allows post-processing of the bean factory in context subclasses. //允许容器的子类去注册postProcessor ,钩子方法 postProcessBeanFactory(beanFactory); // Invoke factory processors registered as beans in the context. // 激活在容器中注册为bean的BeanFactoryPostProcessors //对于注解容器,org.springframework.context.annotation.ConfigurationClassPostProcessor#postProcessBeanDefinitionRegistry //方法扫描应用中所有BeanDefinition并注册到容器之中 invokeBeanFactoryPostProcessors(beanFactory); // Register bean processors that intercept bean creation. // 注册拦截bean创建过程的BeanPostProcessor registerBeanPostProcessors(beanFactory); // Initialize message source for this context. // 找到“messageSource”的Bean提供给ApplicationContext使用, // 使得ApplicationContext具有国际化能力。 initMessageSource(); // Initialize event multicaster for this context. // 初始化ApplicationEventMulticaster该类作为事件发布者, // 可以存储所有事件监听者信息,并根据不同的事件,通知不同的事件监听者。 initApplicationEventMulticaster(); // Initialize other special beans in specific context subclasses. // 预留给 AbstractApplicationContext 的子类用于初始化其他特殊的 bean, // 该方法需要在所有单例 bean 初始化之前调用 // 比如Web容器就会去初始化一些和主题展示相关的Bean(ThemeSource) onRefresh(); // Check for listener beans and register them. // 注册监听器(检查监听器的bean并注册它们) registerListeners(); // Instantiate all remaining (non-lazy-init) singletons. //设置自定义的类型转化器ConversionService, // 设置自定义AOP相关的类LoadTimeWeaverAware, // 清除临时的ClassLoader // ,实例化所有的类(懒加载的类除外) finishBeanFactoryInitialization(beanFactory); // Last step: publish corresponding event. // 初始化容器的生命周期事件处理器,(默认使用DefaultLifecycleProcessor),调用扩展了SmartLifecycle接口的start方法 // 当Spring容器加载所有bean并完成初始化之后,会接着回调实现该接口的类中对应的方法(start()方法) // 并发布容器刷新完毕事件ContextRefreshedEvent给对应的事件监听者 finishRefresh(); } catch (BeansException ex) { if (logger.isWarnEnabled()) { logger.warn("Exception encountered during context initialization - " + "cancelling refresh attempt: " + ex); } // Destroy already created singletons to avoid dangling resources. //销毁已创建的Bean destroyBeans(); // Reset 'active' flag. //取消refresh操作,重置容器的同步标识 cancelRefresh(ex); // Propagate exception to caller. throw ex; } finally { // Reset common introspection caches in Spring's core, since we // might not ever need metadata for singleton beans anymore... // 重置Spring内核中的共用的缓存,因为我们可能再也不需要单例bean的元数据了…… resetCommonCaches(); } } }

registerBeanPostProcessors(beanFactory)

注册拦截bean创建过程的BeanPostProcessor

/** * BeanPostProcessor 的 bean,如果给出显式顺序,请按照顺序。 * 必须在应用程序bean的任何实例化之前调用。 * Instantiate and register all BeanPostProcessor beans, * respecting explicit order if given. * <p>Must be called before any instantiation of application beans. */ protected void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory) { // 1.注册BeanPostProcessor PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this); }

PostProcessorRegistrationDelegate.registerBeanPostProcessors(beanFactory, this)

注册BeanPostProcessor

public static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { // 1.找出所有实现BeanPostProcessor接口的类 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. // 注册 BeanPostProcessorChecker // 主要用于记录一些 bean 的信息,这些 bean 不符合所有 BeanPostProcessors 处理的资格时 // BeanPostProcessor的目标计数 int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length; // 2.添加BeanPostProcessorChecker(主要用于记录信息)到beanFactory中 beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount)); // Separate between BeanPostProcessors that implement PriorityOrdered, // Ordered, and the rest. // 区分 PriorityOrdered、Ordered 、以及非两者 // 3.定义不同的变量用于区分: 实现PriorityOrdered接口的BeanPostProcessor、实现Ordered接口的BeanPostProcessor、普通BeanPostProcessor // 3.1 priorityOrderedPostProcessors: 用于存放实现PriorityOrdered接口的BeanPostProcessor List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>(); // 3.2 internalPostProcessors: 用于存放Spring内部的BeanPostProcessor List<BeanPostProcessor> internalPostProcessors = new ArrayList<>(); // 3.3 orderedPostProcessorNames: 用于存放实现Ordered接口的BeanPostProcessor的beanName List<String> orderedPostProcessorNames = new ArrayList<>(); // 3.4 nonOrderedPostProcessorNames: 用于存放普通BeanPostProcessor的beanName List<String> nonOrderedPostProcessorNames = new ArrayList<>(); // 4.遍历postProcessorNames, 将BeanPostProcessors按3.1 - 3.4定义的变量区分开 for (String ppName : postProcessorNames) { if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { // 4.1 如果ppName对应的Bean实例实现了PriorityOrdered接口, 则拿到ppName对应的Bean实例并添加到priorityOrderedPostProcessors BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); priorityOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { // 4.2 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口, // 则将ppName对应的Bean实例添加到internalPostProcessors internalPostProcessors.add(pp); } } else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { // 4.3 如果ppName对应的Bean实例没有实现PriorityOrdered接口, 但是实现了Ordered接口, 则将ppName添加到orderedPostProcessorNames orderedPostProcessorNames.add(ppName); } else { // 4.4 否则, 将ppName添加到nonOrderedPostProcessorNames nonOrderedPostProcessorNames.add(ppName); } } // First, register the BeanPostProcessors that implement PriorityOrdered. // 5.首先, 注册实现PriorityOrdered接口的BeanPostProcessors // 5.1 对priorityOrderedPostProcessors进行排序 sortPostProcessors(priorityOrderedPostProcessors, beanFactory); // 5.2 注册priorityOrderedPostProcessors registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); // Next, register the BeanPostProcessors that implement Ordered. // 6.接下来, 注册实现Ordered接口的BeanPostProcessors List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size()); for (String ppName : orderedPostProcessorNames) { // 6.1 拿到ppName对应的BeanPostProcessor实例对象 BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); // 6.2 将ppName对应的BeanPostProcessor实例对象添加到orderedPostProcessors, 准备执行注册 orderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { // 6.3 如果ppName对应的Bean实例也实现了MergedBeanDefinitionPostProcessor接口, // 则将ppName对应的Bean实例添加到internalPostProcessors internalPostProcessors.add(pp); } } // 6.4 对orderedPostProcessors进行排序 sortPostProcessors(orderedPostProcessors, beanFactory); // 6.5 注册orderedPostProcessors registerBeanPostProcessors(beanFactory, orderedPostProcessors); // Now, register all regular BeanPostProcessors. // 7.注册所有常规的BeanPostProcessors(过程与6类似) List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size()); for (String ppName : nonOrderedPostProcessorNames) { BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class); nonOrderedPostProcessors.add(pp); if (pp instanceof MergedBeanDefinitionPostProcessor) { internalPostProcessors.add(pp); } } registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors); // Finally, re-register all internal BeanPostProcessors. // 8.最后, 重新注册所有内部BeanPostProcessors(相当于内部的BeanPostProcessor会被移到处理器链的末尾) // 8.1 对internalPostProcessors进行排序 sortPostProcessors(internalPostProcessors, beanFactory); // 8.2注册internalPostProcessors registerBeanPostProcessors(beanFactory, internalPostProcessors); // Re-register post-processor for detecting inner beans as ApplicationListeners, // moving it to the end of the processor chain (for picking up proxies etc). // 重新注册用来自动探测内部ApplicationListener的postprocessor, // 这样可以将他们移到处理器链条的末尾 // 9.重新注册ApplicationListenerDetector(跟8类似,主要是为了移动到处理器链的末尾) beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext)); }

registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors)

注册priorityOrderedPostProcessors

/** * Register the given BeanPostProcessor beans. */ private static void registerBeanPostProcessors( ConfigurableListableBeanFactory beanFactory, List<BeanPostProcessor> postProcessors) { // 1.遍历postProcessors for (BeanPostProcessor postProcessor : postProcessors) { // 2.将PostProcessor添加到BeanFactory中的beanPostProcessors缓存 beanFactory.addBeanPostProcessor(postProcessor); } }

beanFactory.addBeanPostProcessor(postProcessor)

将 PostProcessor 添加到 BeanFactory 中的 beanPostProcessors 缓存

/** * 添加一个新的BeanPostProcessor,在工厂创建bean的时候会应用得到。 * 在工厂配置时被调用。 * 注意:Post-processors是按照注册的顺序被提交的 * 任何通过实现Ordered接口的排序表达式都将被忽略。 * 注意,自动检测的post-processors(作为一个在ApplicationContext的bean)总是在编程方式注册后才会被使用 * @param beanPostProcessor the post-processor to register */ @Override public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) { Assert.notNull(beanPostProcessor, "BeanPostProcessor must not be null"); // Remove from old position, if any //beanPostProcessors是一个ArrayList,持有在创建bean时被应用的BeanPostProcessors // 1.如果beanPostProcessor已经存在则移除(可以起到排序的效果,beanPostProcessor可能本来在前面,移除再添加,则变到最后面) this.beanPostProcessors.remove(beanPostProcessor); // Track whether it is instantiation/destruction aware //InstantiationAwareBeanPostProcessor这个接口有两个方法 //一个在实例化之前被调用 //一个在实例化之后,初始化之前被调用,可以用来做一些特殊用途,比如代理 if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) { // 3.如果beanPostProcessor是InstantiationAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true, // 该变量用于指示beanFactory是否已注册过InstantiationAwareBeanPostProcessors this.hasInstantiationAwareBeanPostProcessors = true; } //DestructionAwareBeanPostProcessor这个接口只有一个方法,在被销毁前调用 if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { // 4.如果beanPostProcessor是DestructionAwareBeanPostProcessor, 则将hasInstantiationAwareBeanPostProcessors设置为true, // 该变量用于指示beanFactory是否已注册过DestructionAwareBeanPostProcessor this.hasDestructionAwareBeanPostProcessors = true; } // Add to end of list // 2.将beanPostProcessor添加到beanPostProcessors缓存 this.beanPostProcessors.add(beanPostProcessor); }

该方法作用就是将 BeanPostProcessor 添加到 beanPostProcessors 缓存,这边的先移除再添加,主要是起一个排序的作用。而 hasInstantiationAwareBeanPostProcessors 和 hasDestructionAwareBeanPostProcessors 变量用于指示 beanFactory 是否已注册过 InstantiationAwareBeanPostProcessors 和 DestructionAwareBeanPostProcessor,在之后的 IoC 创建过程会用到这两个变量,这边先有个印象。

基本使用

使用方法比较简单,新建一个类实现 BeanPostProcessor 接口,并将该类注册到 Spring IoC 容器中。

@Component public class MyBeanPostProcessor implements BeanPostProcessor, PriorityOrdered { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor#postProcessBeforeInitialization"); if (bean instanceof UserService) { System.out.println(beanName); } // 自己的逻辑 return bean; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { System.out.println("MyBeanPostProcessor#postProcessAfterInitialization"); // 自己的逻辑 return bean; } @Override public int getOrder() { return 0; } }

这样,在 Spring 创建 bean 实例时,执行初始化方法前会调用 MyBeanPostProcessor 的 postProcessBeforeInitialization 方法,在执行初始化方法后会调用 MyBeanPostProcessor 的 postProcessAfterInitialization 方法。

总结

如同 invokeBeanFactoryPostProcessors 方法一样,registerBeanPostProcessors 方法的内容也比较少,核心过程在代码块1的注释已经写清楚,这边稍微总结一下。

  • 1、整个 registerBeanPostProcessors 方法围绕 BeanPostProcessor 接口展开,和 invokeBeanFactoryPostProcessors 不同的是,invokeBeanFactoryPostProcessors 方法会直接调用 BeanFactoryPostProcessor 实现类的方法,而 registerBeanPostProcessors 方法只是将 BeanPostProcessor 实现类注册到 BeanFactory 的 beanPostProcessors 缓存中。这是因为,此时还未到 BeanPostProcessor 实现类“出场的时候”。

  • 2、BeanPostProcessor 实现类具体的 “出场时机” 在创建 bean 实例时,执行初始化方法前后。postProcessBeforeInitialization 方法在执行初始化方法前被调用,postProcessAfterInitialization 方法在执行初始化方法后被调用。

  • 3、BeanPostProcessor 实现类和 BeanFactoryPostProcessor 实现类一样,也可以通过实现 PriorityOrdered、Ordered 接口来调整自己的优先级。

  • 4、registerBeanPostProcessors 方法和 invokeBeanFactoryPostProcessors 也会触发 bean 实例的创建,创建 Bean 实例是 IoC 的核心内容,之后会单独解析,目前暂不深入解析。

参考: https://zhuanlan.zhihu.com/p/83474370

上一篇:Spring5 IOC容器解析——refresh()方法分析
下一篇:没有了
网友评论