Spring启动过程中实例化前部分的分析
2022/9/13 23:22:15
本文主要是介绍Spring启动过程中实例化前部分的分析,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
代码部分
说明
1.hasInstantiationAwareBeanPostProcessors()方法说明
其实是判断 AbstractBeanFactory类的hasInstantiationAwareBeanPostProcessors中 是否标志有处理器( 5.3版本后其实是存放于BeanPostProcessorCache中,里面有四个List都是用于存放各种处理器的缓存,不用多做在意,因为5.3之后都是一次性全部遍历存完,优化了部分)
2.applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) 方法说明
该方法作用有两种,一种是修改对象实例元数据(因为还没被创建,所以元数据的改动会导致实例的改动),一种是提前返回Bean对象(可以返回自己定义的某个对象实例)
3.applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) 方法说明
该方法为初始化后的调用方法,为什么如果bean创建后要调用呢? 因为这个方法与AOP有关,在这个方法中进行AOP,是每个bean都要进行处理的方法,在这个方法内判断需不需要进行动态代理,不需要就返回本身,需要就进行动态代理。(具体可查看 Spring的AOP底层解析 )
代码展示
protected Object resolveBeforeInstantiation(String beanName, RootBeanDefinition mbd) { Object bean = null; if (!Boolean.FALSE.equals(mbd.beforeInstantiationResolved)) { if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) { Class<?> targetType = determineTargetType(beanName, mbd); if (targetType != null) { bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName); if (bean != null) { bean = applyBeanPostProcessorsAfterInitialization(bean, beanName); } } } mbd.beforeInstantiationResolved = (bean != null); } return bean; }
版本区别的记录展示
applyBeanPostProcessorsBeforeInstantiation方法的差异(applyBeanPostProcessorsAfterInitialization方法类似,就写出来了)
说明
1.改进后的版本明显会比之前版本要快,而且会简化一点,因为BeanPostProcessor的全部遍历只会进行一次,而不是每个Bean都会全部遍历一次。(这里面涉及到策略设计模式,本质上取决于,如果bean被创建出来了,后面的处理器其实就不会被调用)
2.以空间换时间的思维更加明显,相比于名称都要拿出全部的BeanPostProcessor进行遍历(而且某些类型还不是需要的),不如按照类型进行划分缓存,虽说消耗了一定量的空间,但是能更快速的按照类型拿出需要的BeanPostProcessor进行遍历处理
代码展示
//5.3之前的版本 protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { 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; } //5.3之后的版本 static class BeanPostProcessorCache { final List<InstantiationAwareBeanPostProcessor> instantiationAware = new ArrayList<>(); final List<SmartInstantiationAwareBeanPostProcessor> smartInstantiationAware = new ArrayList<>(); final List<DestructionAwareBeanPostProcessor> destructionAware = new ArrayList<>(); final List<MergedBeanDefinitionPostProcessor> mergedDefinition = new ArrayList<>(); } BeanPostProcessorCache getBeanPostProcessorCache() { BeanPostProcessorCache bpCache = this.beanPostProcessorCache; if (bpCache == null) { bpCache = new BeanPostProcessorCache(); for (BeanPostProcessor bp : this.beanPostProcessors) { if (bp instanceof InstantiationAwareBeanPostProcessor) { bpCache.instantiationAware.add((InstantiationAwareBeanPostProcessor) bp); if (bp instanceof SmartInstantiationAwareBeanPostProcessor) { bpCache.smartInstantiationAware.add((SmartInstantiationAwareBeanPostProcessor) bp); } } if (bp instanceof DestructionAwareBeanPostProcessor) { bpCache.destructionAware.add((DestructionAwareBeanPostProcessor) bp); } if (bp instanceof MergedBeanDefinitionPostProcessor) { bpCache.mergedDefinition.add((MergedBeanDefinitionPostProcessor) bp); } } this.beanPostProcessorCache = bpCache; } return bpCache; } protected Object applyBeanPostProcessorsBeforeInstantiation(Class<?> beanClass, String beanName) { for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache().instantiationAware) { Object result = bp.postProcessBeforeInstantiation(beanClass, beanName); if (result != null) { return result; } } return null; }
applyBeanPostProcessorsAfterInitialization
这篇关于Spring启动过程中实例化前部分的分析的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-04-2203-为啥大模型LLM还没能完全替代你?
- 2024-04-2101-大语言模型发展
- 2024-04-17基于SpringWeb MultipartFile文件上传、下载功能
- 2024-04-14个人开发者,Spring Boot 项目如何部署
- 2024-04-14RAG应用开发实战02-相似性检索的关键 - Embedding
- 2024-04-14出海软件草根逆袭打法是什么?
- 2024-04-13鸿蒙原生应用再新丁!企查查 碧蓝航线 入局鸿蒙
- 2024-04-11RAG应用开发实战(01)-RAG应用框架和解析器
- 2024-04-10DevOps已死?2024年的DevOps将如何发展
- 2024-04-10码农必看:常见源代码混淆技术详解