Spring源码 – 核心接口BeanPostProcessor[通俗易懂]

Spring源码 – 核心接口BeanPostProcessor[通俗易懂]Spring源码-核心接口BeanPostProcessor

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

Spring源码 – 核心接口BeanPostProcessor

Spring版本:Spring 5.3.13-release


# 1、核心接口BeanPostProcessor

BeanPostProcessor接口我们一般称为后置处理器或者增强器。

BeanPostProcessor接口是Spring本着开闭原则(面对修改关闭面对扩展开放)设计的一个接口。

BeanPostProcessor接口允许开发者在Bean实例化前后对Bean做一些定制化处理,如修改BeanDefinition等。

BeanPostProcessor接口代码:

public interface BeanPostProcessor { 
   

	/** * Apply this {@code BeanPostProcessor} to the given new bean instance <i>before</i> any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. * <p>The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet */
	@Nullable
	default Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { 
   
		return bean;
	}

	/** * Apply this {@code BeanPostProcessor} to the given new bean instance <i>after</i> any bean * initialization callbacks (like InitializingBean's {@code afterPropertiesSet} * or a custom init-method). The bean will already be populated with property values. * The returned bean instance may be a wrapper around the original. * <p>In case of a FactoryBean, this callback will be invoked for both the FactoryBean * instance and the objects created by the FactoryBean (as of Spring 2.0). The * post-processor can decide whether to apply to either the FactoryBean or created * objects or both through corresponding {@code bean instanceof FactoryBean} checks. * <p>This callback will also be invoked after a short-circuiting triggered by a * {@link InstantiationAwareBeanPostProcessor#postProcessBeforeInstantiation} method, * in contrast to all other {@code BeanPostProcessor} callbacks. * <p>The default implementation returns the given {@code bean} as-is. * @param bean the new bean instance * @param beanName the name of the bean * @return the bean instance to use, either the original or a wrapped one; * if {@code null}, no subsequent BeanPostProcessors will be invoked * @throws org.springframework.beans.BeansException in case of errors * @see org.springframework.beans.factory.InitializingBean#afterPropertiesSet * @see org.springframework.beans.factory.FactoryBean */
	@Nullable
	default Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { 
   
		return bean;
	}

}

BeanPostProcessor接口中定义了两个方法:

  • 1、postProcessBeforeInitialization(Object bean, String beanName):在Bean实例化、依赖注入完毕,在调用显示的初始化之前完成一些定制的初始化操作。
  • 2、postProcessAfterInitialization(Object bean, String beanName):在Bean实例化、依赖注入、初始化完毕时执行。

可以看出postProcessBeforeInitialization()方法是SpringBean进行初始化之前的回调,postProcessAfterInitialization()方法是SpringBean初始化完成之后的回调。


# 2、BeanPostProcessor的注册

BeanPostProcessor的注册是在Spring进行容器刷新中的AbstractApplicationContext#registerBeanPostProcessors()方法中完成的。而具体的逻辑实现Spring则是委派给PostProcessorRegistrationDelegate#registerBeanPostProcessors()方法进行具体的注册实现。

	public static void registerBeanPostProcessors(ConfigurableListableBeanFactory beanFactory, AbstractApplicationContext applicationContext) { 
   

		// WARNING: Although it may appear that the body of this method can be easily
		// refactored to avoid the use of multiple loops and multiple lists, the use
		// of multiple lists and multiple passes over the names of processors is
		// intentional. We must ensure that we honor the contracts for PriorityOrdered
		// and Ordered processors. Specifically, we must NOT cause processors to be
		// instantiated (via getBean() invocations) or registered in the ApplicationContext
		// in the wrong order.
		//
		// Before submitting a pull request (PR) to change this method, please review the
		// list of all declined PRs involving changes to PostProcessorRegistrationDelegate
		// to ensure that your proposal does not result in a breaking change:
		// https://github.com/spring-projects/spring-framework/issues?q=PostProcessorRegistrationDelegate+is%3Aclosed+label%3A%22status%3A+declined%22

		// 获取所有的 BeanPostProcessor 的 BeanName
		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.
		int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;

		// BeanPostProcessorChecker 是一个普通的信息打印
		// 可能存在有些情况当 Spring 配置中的后置处理器还没有被注册就已经开始 Bean 的实例化了, 这个时候就会打印出 BeanPostProcessorChecker 中设定的信息
		beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));

		// Separate between BeanPostProcessors that implement PriorityOrdered,
		// Ordered, and the rest.
		// 用于保存实现了 PriorityOrdered 排序接口的 BeanPostProcessor
		List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
		// 用于保存 MergedBeanDefinitionPostProcessor 类型 BeanPostProcessor
		List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
		// 用于保存实现了 Ordered 排序接口的 BeanPostProcessor 的 BeanName
		List<String> orderedPostProcessorNames = new ArrayList<>();
		// 用于保存没有实现任何排序接口的 BeanPostProcessor 的 BeanName
		List<String> nonOrderedPostProcessorNames = new ArrayList<>();
		// 遍历所有的 BeanPostProcessor 的 BeanName, 按照不同筛选条件放入相应的容器中
		for (String ppName : postProcessorNames) { 
   
			// 如果实现了 PriorityOrdered 排序接口
			if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { 
   
				// 根据 BeanName 获取 Bean 实例并放入 priorityOrderedPostProcessors 中
				BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
				priorityOrderedPostProcessors.add(pp);
				// 如果是 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor 继续放入 internalPostProcessors 中
				if (pp instanceof MergedBeanDefinitionPostProcessor) { 
   
					internalPostProcessors.add(pp);
				}
			}
			// 如果实现了 Ordered 排序接口
			else if (beanFactory.isTypeMatch(ppName, Ordered.class)) { 
   
				// 将 BeanName 放入 orderedPostProcessorNames 中
				orderedPostProcessorNames.add(ppName);
			}
			// 没有实现任何排序接口
			else { 
   
				// 将 BeanName 放入 nonOrderedPostProcessorNames 中
				nonOrderedPostProcessorNames.add(ppName);
			}
		}

		// First, register the BeanPostProcessors that implement PriorityOrdered.
		// 对实现了 PriorityOrdered 排序接口的 BeanPostProcessor 进行排序
		sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
		// 根据排序结果依次注册 BeanPostProcessor 到 BeanFactory 中,
		// 实际就是将排序后的 BeanPostProcessor 保存到 AbstractBeanFactory#beanPostProcessors 容器中
		registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors);

		// Next, register the BeanPostProcessors that implement Ordered.
		// 创建一个容器用于存放实现了 Ordered 排序接口的 BeanPostProcessor
		List<BeanPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
		// 遍历实现了 Ordered 排序接口的 BeanPostProcessor 的 BeanName
		for (String ppName : orderedPostProcessorNames) { 
   
			// 根据 BeanName 获取 Bean 实例并放入 orderedPostProcessors 中
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			orderedPostProcessors.add(pp);
			// 如果是 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor 继续放入 internalPostProcessors 中
			if (pp instanceof MergedBeanDefinitionPostProcessor) { 
   
				internalPostProcessors.add(pp);
			}
		}
		// 对实现了 Ordered 排序接口的 BeanPostProcessor 的 Bean 实例进行排序
		sortPostProcessors(orderedPostProcessors, beanFactory);
		// 根据排序结果依次注册 BeanPostProcessor 到 BeanFactory 中,
		// 实际就是将排序后的 BeanPostProcessor 保存到 AbstractBeanFactory#beanPostProcessors 容器中
		registerBeanPostProcessors(beanFactory, orderedPostProcessors);

		// Now, register all regular BeanPostProcessors.
		// 创建一个容器用于存放没有实现任何排序接口的 BeanPostProcessor
		List<BeanPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
		// 遍历没有实现任何排序接口的 BeanPostProcessor 的 BeanName
		for (String ppName : nonOrderedPostProcessorNames) { 
   
			// 根据 BeanName 获取 Bean 实例并放入 nonOrderedPostProcessors 中
			BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
			nonOrderedPostProcessors.add(pp);
			// 如果是 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor 继续放入 internalPostProcessors 中
			if (pp instanceof MergedBeanDefinitionPostProcessor) { 
   
				internalPostProcessors.add(pp);
			}
		}
		// 注册 BeanPostProcessor 到 BeanFactory 中
		registerBeanPostProcessors(beanFactory, nonOrderedPostProcessors);

		// Finally, re-register all internal BeanPostProcessors.
		// 对 MergedBeanDefinitionPostProcessor 类型的 BeanPostProcessor 进行排序
		sortPostProcessors(internalPostProcessors, beanFactory);
		// 注册 BeanPostProcessor 到 BeanFactory 中, 注册时会先执行移除已存在的 BeanPostProcessor 然后在进行添加
		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 注册和销毁的 BeanPostProcessor
		beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(applicationContext));
	}

BeanPostProcessor的注册逻辑也是非常清晰:按照BeanPostProcessor实现的排序接口依次进行注册。

需要注意的是,这里仅仅是完成BeanPostProcessor的注册工作,此时BeanPostProcessor类型的Bean已经注册到SpringIOC容器中,并且由AbstractBeanFactory中的beanPostProcessors持有一份已注册的缓存副本。


# 3、BeanPostProcessor的激活

BeanPostProcessor的激活是在Spring初始化Bean时完成。

AbstractAutowireCapableBeanFactory#initializeBean()代码:

	protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { 
   
		// 如果安全管理器不为空
		if (System.getSecurityManager() != null) { 
   
			// 以特权的方式执行回调 Bean 中的 Aware 接口方法
			AccessController.doPrivileged((PrivilegedAction<Object>) () -> { 
   
				invokeAwareMethods(beanName, bean);
				return null;
			}, getAccessControlContext());
		}
		else { 
   
			// Aware 接口处理器, 调用 BeanNameAware、BeanClassLoaderAware、BeanFactoryAware
			invokeAwareMethods(beanName, bean);
		}

		Object wrappedBean = bean;
		// 如果 RootBeanDefinition 不为空 || RootBeanDefinition 不是 synthetic。一般指只有 AOP 相关的 PointCut 配置或者 Advice 配置才会将 synthetic 设置为 true
		if (mbd == null || !mbd.isSynthetic()) { 
   
			// 将 BeanPostProcessor 应用到给定的现有 Bean 实例, 调用它们的 PostProcessorsBeforeInitialization 初始化方法
			// 返回的 Bean 实例可能是原始 Bean 包装器
			// 执行 applyBeanPostProcessorsBeforeInitialization 方法后会将 ApplicationContext 注入进来
			wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
		}

		try { 
   
			// 调用初始化方法, 先调用 Bean 的 InitializeBean 接口方法, 后调用 Bean 的自定义初始化方法
			// invokeInitMethods() 方法的作用是执行初始化方法, 这些初始化方法包括 :
			// 1.在 XML 文件中的 <bean></bean> 标签中使用的 init-method 属性的 Bean 初始化方法;
			// 2.在 @Bean 注解中使用 initMethod 属性指定的 Bean 初始化方法;
			// 3.使用 @PostConstruct 注解标注的方法;
			// 4.实现 InitializingBean 接口的方法等;
			invokeInitMethods(beanName, wrappedBean, mbd);
		}
		catch (Throwable ex) { 
   
			// 捕捉调用初始化方法时抛出的异常, 重新抛出 Bean 创建异常 : 调用初始化方法失败
			throw new BeanCreationException(
					(mbd != null ? mbd.getResourceDescription() : null),
					beanName, "Invocation of init method failed", ex);
		}

		// 如果 RootBeanDefinition 不为空 || RootBeanDefinition 不是 synthetic
		if (mbd == null || !mbd.isSynthetic()) { 
   
			// 将 BeanPostProcessor 应用到给定的现有 Bean 实例, 调用它们的 postProcessAfterInitialization 方法
			// 返回的 Bean 实例可能是原始 Bean 包装器
			wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
		}

		// 返回包装后的 Bean
		return wrappedBean;
	}

可以看到在SpringBean完全实例化之前调用了applyBeanPostProcessorsBeforeInitialization()方法,在Bean完全实例化之后调用了applyBeanPostProcessorsAfterInitialization()方法。

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization()代码:

	public Object applyBeanPostProcessorsBeforeInitialization(Object existingBean, String beanName)
			throws BeansException { 
   

		// 初始化返回结果为 existingBean
		Object result = existingBean;
		// 遍历, 该工厂创建的 Bean 的 BeanPostProcessors 列表
		for (BeanPostProcessor processor : getBeanPostProcessors()) { 
   
			// postProcessBeforeInitialization : 在任何 Bean 初始化回调之前(如初始化 Bean 的 afterPropertiesSet 或自定义的 init 方法)
			// 将此 BeanPostProcessor 应用到给定的新 Bean 实例。Bean 已经填充了属性值。返回的 Bean 实例可能是原始 Bean 的包装器
			// 默认实现按原样返回给定的 Bean
			Object current = processor.postProcessBeforeInitialization(result, beanName);

			// 如果 current 为空。即一旦 Bean 的 BeanPostProcessors 中的某一个增强处理器返回 null, 后续 BeanPostProcessor 对象的 postProcessBeforeInitialization 方法不在执行, 直接退出后续循环
			if (current == null) { 
   
				// 直接返回 result, 中断其后续的 BeanPostProcessor 处理器
				return result;
			}
			// 让 result 引用 processor 返回的结果, 使其经过所有 BeanPostProcessor 对象的后置处理器的层层包装
			result = current;
		}
		// 返回经过所有 BeanPostProcessor 对象的后置处理器的层层包装后的 result
		return result;
	}

Spring会获取在AbstractBeanFactory中持有的已经注册完成的BeanPostProcessor实例。获取到之后根据顺序依次激活。调用postProcessBeforeInitialization()Bean进行包装并返回。如果其中某一个BeanPostProcessor返回的结果为null,则中断执行后续的BeanPostProcessor,直接返回当前结果。

AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization()代码:

	public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName)
			throws BeansException { 
   

		Object result = existingBean;

		// 获取创建 Bean 实例对象过程中所有的 BeanPostProcessors(Bean后置处理器)
		for (BeanPostProcessor processor : getBeanPostProcessors()) { 
   
			// 如果 Bean 被子类标记为代理, 则使用配置的拦截器创建一个代理
			Object current = processor.postProcessAfterInitialization(result, beanName);
			// 如果某一个 BeanPostProcessor 返回 null, 则中断后续所有 BeanPostProcessor 的激活, 直接放回当前结果
			if (current == null) { 
   
				return result;
			}
			// 让 result 引用 processor 返回的结果, 使其经过所有 BeanPostProcessor 对象的后置处理器的层层包装
			result = current;
		}
		// 返回经过所有 BeanPostProcessor 对象的后置处理器的层层包装后的 result
		return result;
	}

逻辑与applyBeanPostProcessorsBeforeInitialization()方法类型。也是先获取所有的BeanPsotProcessor实例副本,然后依次执行激活。

GitHub源码地址https://github.com/kapbc/kapcb-spring-source/tree/master/Spring-Framework-v5.3.13

备注:此文为笔者学习Spring源码的笔记,鉴于本人技术有限,文中难免出现一些错误,感谢大家批评指正。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/170022.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)


相关推荐

  • 优先级队列详解

    优先级队列详解动力节点小编来为大家进行优先级队列详解,优先级队列是一种特殊类型的队列,其中每个元素都与一个优先级值相关联。并且,元素根据其优先级提供服务。即,首先服务更高优先级的元素。但是,如果出现具有相同优先级的元素,则按照它们在队列中的顺序提供服务。分配优先级值通常,在分配优先级时考虑元素本身的值。例如,具有最高值的元素被认为是最高优先级的元素。但是,在其他情况下,我们可以假设具有最低值的元素作为最高优先级元素。我们还可以根据需要设置优先级。优先队列和普通队列的区别在队列中,执行先进先

  • ora 01017问题解决办法

    ora 01017问题解决办法SQL&gt;startup ORACLEinstancestarted. TotalSystemGlobalArea 914358272bytes FixedSize                 2088184bytes VariableSize            528483080bytes DatabaseBuffers         3774873…

  • 推荐几个基于.net的cms系统

    推荐几个基于.net的cms系统 建站必备啊,.net的不如PHP的那么多那么好用,这几个也还可以了。

  • phpstorm 激活码【注册码】

    phpstorm 激活码【注册码】,https://javaforall.cn/100143.html。详细ieda激活码不妨到全栈程序员必看教程网一起来了解一下吧!

  • pycharm激活码2021【2021最新】[通俗易懂]

    (pycharm激活码2021)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.cn/100143.html9ZHRNTE33T-eyJsaWNlbnNlSW…

  • 国内服务器免备案访问教程是什么_国外服务器国内域名要不要备案

    国内服务器免备案访问教程是什么_国外服务器国内域名要不要备案首先我们需要准备:1.国内服务器一台2.一级域名一个3.免费免备案的CDNNodecache(百度搜索即可,可通过无限注册来一直白嫖)首先打开宝塔面板添加一个网站,然后去域名解析到你的服务器!(以获得一个源站域名)现在开始进入Nodecache进行cdn设置首先我们注册登录要创建CDN服务然后开始配置CDN服务信息(具体配置请看图)服务名称随便填加速域名就是你要访问的域名源站地址就是你的服务器ip端口跟着我填8866地区选择中国直连复制打.

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号