博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
精通 Spring 源码 | InstantiationAwareBeanPostProcessor(1)
阅读量:4104 次
发布时间:2019-05-25

本文共 4059 字,大约阅读时间需要 13 分钟。

一、简介

InstantiationAwareBeanPostProcessor 是 Spring 的一个扩展点,他是 BeanPostProcessor 的子类,扩展了 BeanPostProcessor ,而外提供了 3 个方法:

1、Object postProcessBeforeInstantiation(Class<?> beanClass, String beanName)

2、boolean postProcessAfterInstantiation(Object bean, String beanName)
3、PropertyValues postProcessPropertyValues(PropertyValues pvs, PropertyDescriptor[] pds, Object bean, String beanName)

二、源码分析

本篇我们来探究 postProcessBeforeInstantiation 这个方法的作用,这个方法会返回一个 Object 类型的对象,在源码里面,如果有一个类实现了 InstantiationAwareBeanPostProcessor 这个后置处理器,在 postProcessBeforeInstantiation 方法里面返回了一个对象,那么直接返回,后续只会实现 BeanPostProcessor 的 postProcessAfterInitialization 方法,否则,按照正常流程走。我们可以看看源码:

Object bean = resolveBeforeInstantiation(beanName, mbdToUse);			//如果bean不为空直接返回			if (bean != null) {				return bean;			}
@Nullable	protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) {		Object bean = null;		if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) {			// Make sure bean class is actually resolved at this point.			if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {				Class
targetType = determineTargetType(beanName, mbd); if (targetType != null) { //1、调用 InstantiationAwareBeanPostProcessor 的 postProcessBeforeInstantiation 方法 bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { //2、调用 BeanPostProcessor 的 postProcessAfterInitialization 方法 bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }

下面的方法里面实现的是 postProcessBeforeInstantiation 这个方法

bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
@Nullable	protected Object applyBeanPostProcessorsBeforeInstantiation(Class
beanClass, String beanName) { //拿到实现了BeanPostProcessors的接口 for (BeanPostProcessor bp : getBeanPostProcessors()) { if (bp instanceof InstantiationAwareBeanPostProcessor) { InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp; Object result = ibp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } } return null; }

默认情况上面的方法返回的是空,如果不为空, 调用 BeanPostProcessor 的 postProcessAfterInitialization 方法

if (bean != null) {//2、调用 BeanPostProcessor 的 postProcessAfterInitialization 方法   bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);}

之后便是直接返回得到 Bean

三、示例

源码比较复杂,可能文字无法表达清楚,下面通过具体代码演示结果

@ComponentScan("com.javahly.spring59")@Configurationpublic class Appconfig {}
@Componentpublic class IndexService {}
@Componentpublic class OrderService {}
@Componentpublic class UserService {}
@Componentpublic class MyInstantiationAwareBeanPostProcessor implements InstantiationAwareBeanPostProcessor {	@Override	public Object postProcessBeforeInstantiation(Class
beanClass, String beanName) throws BeansException { if (beanName.endsWith("indexService")) return new UserService(); return null; }}
public class Test {	public static void main(String[] args){		AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext();		applicationContext.register(Appconfig.class);		applicationContext.refresh();		System.out.println("orderService:"+applicationContext.getBean("orderService"));		System.out.println("userService:"+applicationContext.getBean("userService"));		System.out.println("indexService:"+applicationContext.getBean("indexService"));		System.out.println("indexService:"+applicationContext.getBean("indexService"));	}}

这里我们把三个对象使用 @Component 标注,依旧是说我们想把这三个对象注入容器,不出意外,我们在运行 main 方法的时候会打印出这三个对象,但是,我们自定义了一个 MyInstantiationAwareBeanPostProcessor 扩展了InstantiationAwareBeanPostProcessor,住了一个偷梁换柱,把原本需要放入容器的 indexService 换成了 userService,打印结果如下:

orderService:com.javahly.spring59.service.OrderService@d7b1517

userService:com.javahly.spring59.service.UserService@16c0663d
indexService:com.javahly.spring59.service.UserService@23223dd8
indexService:com.javahly.spring59.service.UserService@23223dd8

—— 完

ABOUT

公众号:【星尘Pro】

github:

推荐阅读

转载地址:http://yffsi.baihongyu.com/

你可能感兴趣的文章
【增强学习在无人驾驶中的应用】
查看>>
OpenCV meanshift目标跟踪总结
查看>>
人工神经网络——神经元模型介绍
查看>>
Windows 窗口底层原理
查看>>
一种函数指针的运用
查看>>
今天,Python信息量很大!
查看>>
Flash 已死,Deno 当立?
查看>>
编程差的程序员,90%都是吃了数学的亏!骨灰级开发:方法不对,努力也白费...
查看>>
都无代码了,还要程序员吗?
查看>>
面试想拿 10K,HR 说我只配7k?
查看>>
那些人生“开挂”的程序员,都在干什么?
查看>>
影响科学圈的那些计算机代码
查看>>
乐视视频 App 图标改为“欠 122 亿”,网友:我在别家分红包,却在你家随份子!...
查看>>
为何程序员总喜欢写技术博客,看完恍然大悟...
查看>>
假如计算机是中国人发明的,那代码应该这么写
查看>>
触目惊心:比特币到底消耗了多少能源?
查看>>
如何判断一家互联网公司要倒闭了?
查看>>
想快速上手机器学习?来看下这个 GitHub 项目!
查看>>
GitHub 标星 3.6k,一本开源的深度学习中文教程!
查看>>
9 款你不能错过的 JSON 工具
查看>>