【保姆级·创建对象】如何通过Supplier创建对象
【Spring源码系列- IOC】
1 |
【Spring源码】0.安装Gradle环境 |
|
2 |
【Spring源码】1.下载与编译_pom relocation to an other version number is not f |
|
3 |
【Spring源码】2.试个水先~Debug找到传说中的三级缓存(图解向,堆图预警) |
|
4 |
【Spring源码】3. xml文件如何转换成BeanDefinition(主要涉及prepareRefresh()+ obtainFreshBeanFactory()两个函数,图解向,堆图预警)_spring xml转bean |
|
5 |
【Spring源码】4. 自己搞个标签?~自定义标签保姆级全过程(图解向,堆图预警) |
|
6 |
【Spring源码】5.spring的bean工厂准备工作(prepareBeanFactory(beanFactory) |
|
7 |
【Spring源码】6. Spring扩展自定义属性编辑器保姆级教程 |
|
8 |
【Spring源码】7. 如何添加自定义的BeanFactoryPostProcessor |
|
9 |
【Spring源码】8. 捋下invokeBeanFactoryPostProcessors()主要处理流程 |
|
10 |
【Spring源码】9. 超级重要的ConfigurationClassPostProcessor |
|
11 |
【Spring源码】10. 递归调用的processConfigurationClass()方法 |
|
12 |
【Spring源码】11. 我是注解类不?checkConfigurationClassCandidate()注解类判断方法详解 |
|
13 |
【Spring源码】12. 注册bean处理器registerBeanPostProcessors() |
|
14 |
【Spring源码】13. 国际化处理initMessageSource()源码解析 |
【补充内容】【保姆级】SpringBoot项目中的i18n国际化 |
15 |
【Spring源码】14. 消息多播器(观察者模式) |
【补充内容】【保姆级示例向】观察者模式 |
16 |
【Spring源码】15. Bean的创建过程(1.概述篇) |
|
17 |
【Spring源码】16. Bean的创建过程(2) |
|
18 |
【Spring源码】17.创建Bean这篇认真的@(・●・)@ |
【补充内容】 【保姆级·创建对象】如何通过Supplier创建对象 【保姆级·创建对象】如何通过factory-method创建对象 【保姆级·创建对象】如何利用resolveBeforeInstantiation()在预处理阶段返回一个Bean的实例对象 |
19 |
【Spring源码】18. factory-method创建对象关键函数详解:instantiateUsingFactoryMethod() |
|
20 |
【Spring源码】19. 没合适的构造器?找determineCandidateConstructors()! |
|
21 |
【Spring源码】20. MergedBeanDefinitionPostProcessor修改/合并bean定义 |
【补充内容】 【保姆级】@PostConstruct & @PreDestroy使用示例 【Spring源码】AutowiredAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()详解 【Spring源码】CommonAnnotationBeanPostProcessor.postProcessMergedBeanDefinition()详解 |
22 |
【Spring源码】21. 初探循环依赖 |
【补充内容】 【保姆级】手把手Debug循环依赖的整体流程 【实践向】当移除了三级缓存…… 【分析向】没有三级缓存会导致什么? 【Spring源码】插播一个创建代理对象的wrapIfNecessary()方法 |
23 |
【Spring源码】22. 属性填充populateBean()详解 |
【补充内容】 【Spring源码】自动注入·名称:autowireByName()详解 【Spring源码】自动注入·类型:autowireByType()详解 【Spring源码】属性值的解析与赋值:populateBean().applyPropertyValues() 【保姆级】超超超简单的自定义注解实现@Autowired同款功能 |
24 |
【Spring源码】23. 执行初始化逻辑:initializeBean() |
本文目录
创建测试所需文件
User.java
CreateSupplier.java
SupplierBeanFactoryPostProcessor.java
supplier.xml
TestSupplier.java
测试效果
Debug
Spring创建对象的主要方式有
通过自定义BeanPostProcessor,生成代理对象InstantiationAwareBeanPostProcessor
createBean() -> resolveBeforeInstantiation()
通过supplier创建对象
createBean() -> doCreateBean() -> createBeanInstance() -> obtainFromSupplier()
通过FactoryMethod创建对象
createBean() -> doCreateBean() -> createBeanInstance() -> instantiateUsingFactoryMethod()
通过反射创建对象
createBean() -> doCreateBean() -> createBeanInstance() -> instantiateBean()
通过FactoryBean创建对象
本文介绍下最后一种,如何通过supplier创建Bean(保姆级教程,建议收藏食用(。・ω・。)ノ)
创建测试所需文件
User.java
public class User {private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public User(){}public User(String name) {this.name = name;}
}
CreateSupplier.java
public class CreateSupplier {public static User createUser() {return new User("aqin");}
}
SupplierBeanFactoryPostProcessor.java
public class SupplierBeanFactoryPostProcessor implements BeanFactoryPostProcessor {@Overridepublic void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {BeanDefinition beanDefinition = beanFactory.getBeanDefinition("user");GenericBeanDefinition genericBeanDefinition = (GenericBeanDefinition) beanDefinition;genericBeanDefinition.setInstanceSupplier(CreateSupplier::createUser);genericBeanDefinition.setBeanClass(User.class);}
}
supplier.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd"><bean id="user" class="com.aqin.custom.supplier.User"></bean><bean id="supplierBeanFactoryPostProcessor" class="com.aqin.custom.supplier.SupplierBeanFactoryPostProcessor"></bean>
</beans>
TestSupplier.java
public class TestSupplier {public static void main(String[] args) {ApplicationContext applicationContext = new ClassPathXmlApplicationContext("supplier.xml");User user = applicationContext.getBean(User.class);System.out.println(user.getName());}
}
测试效果
Debug
由于是测试创建Bean,我们需要在doCreateBean()上打个断点,启动debug,执行到断点位置,如下图:
进入doCreateBean(),下一步到instanceWrapper = createBeanInstance(beanName, mbd, args);,进入createBeanInstance()方法中
进入createBeanInstance()方法后,下一步到Supplier<?> instanceSupplier = mbd.getInstanceSupplier();这里是判断当前beanDefinition中是否包含实例供应器的
继续下一步,我们会发现instanceSupplier=null,咦?……不应该呀?
不用着急,我们仔细看上图中红框框圈住的内容,有一个是beanName,此时,beanName是"supplierBeanFactoryPostProcessor",并非我们要创建的"user"
所以我们直接点击下图中的Resume Program再次进入之前的断点即可
点击上图中的绿三角,就会再次停在一开始我们打断点的位置,如下图:
此时可以看到,当前处理对象的beanName为"user",继续下一步,直到再次执行到Supplier<?> instanceSupplier = mbd.getInstanceSupplier()
进入getInstanceSupplier(),可以发现instanceWrapper已经不是null叻
再向下执行一步,由于instanceSupplier已经有了值,所以会进入if的逻辑,通过obtainFromSupplier()方法返回已获取到的对象
obtainFromSupplier()从给定“供应商”处,获取Bean实例
然后包装一下,再进行初始化
完成(。・ω・。)ノ
【保姆级·创建对象】如何通过Supplier创建对象相关推荐
- 【Spring源码】4. 自己搞个标签?~自定义标签保姆级全过程(图解向,堆图预警)
[Spring源码系列- IOC] 1 [Spring源码]0.安装Gradle环境 2 [Spring源码]1.下载与编译_pom relocation to an other version nu ...
- 【保姆级】lookup-method标签实践与分析
[Spring源码系列- IOC] 1 [Spring源码]0.安装Gradle环境 2 [Spring源码]1.下载与编译_pom relocation to an other version nu ...
- Java基础 (适合新手入门保姆级)
基础1 1.进制的转换 1. 十进制数据转成二进制数据:使用除以2获取余数的方式 2. 二进制(0B/b开头)转换为十进制:1001 = 1*2^0+0*2^1+0*2^2 +1*2^3 = 9 3. ...
- JavaScript保姆级教程 ——— 重难点详细解析(万字长文,建议收藏)
JavaScript保姆级教程 --- 重难点详细解析(建议收藏) 1. JS函数 2. JS事件 3. JavaScript 对象 4. JavaScript prototype(原型对象) 5. ...
- 女友问粉丝过万如何庆祝,我发万字长文《保姆级大数据入门篇》感恩粉丝们支持,学姐|学妹|学弟|小白看了就懂
2021大数据领域优质创作博客,带你从入门到精通,该博客每天更新,逐渐完善大数据各个知识体系的文章,帮助大家更高效学习. 有对大数据感兴趣的可以关注微信公众号:三帮大数据 目录 粉丝破万了 新星计划申 ...
- 保姆级NLP学习路线来啦!
这个保姆级不是形容这份指南有多详细,而是形容这个指南会伴随你们一起成长哟(其实就是太多了写不完).之后的更新都会定期发文并汇总在Github上,欢迎催更: https://github.com/lee ...
- 这可能是东半球最保姆级的后台服务器开发学习路线
作者 | 编程指北 来源 | 编程指北(id :cs_dev) 前言 这一篇的主题是「Linux C/C++ 服务器/后台开发学习路线」. 这样的文章相信大家都见得不少了,写之前也非常忐忑,能不能和其 ...
- 重磅推荐:保姆级Java技术图谱!够学到元宵节了,赶紧收藏!
最近因为参与社群交流的时间比较多,除了唠唠白酒的嗑之外,很大一部分时间都是看到群里问到一些关于Spring Boot和Spring Cloud应用过程中碰到的问题以及一些开发过程中的报错信息.在这些帮 ...
- 判断是不是链接 正则_Python 正则表达式 保姆级教程,小学生都看得懂!!
~点击 蓝字 关注,获取更多资源~ 0 前言 上一篇文章,2020,还不会正则???,和小伙伴们一起学习了 Python 中的正则表达式,读完之后,总感觉少了点什么东西,无法尽兴?就好像爱你们的心少了 ...
最新文章
- unity3d发布linux版本_微软发布 Linux 版本 Microsoft Defender ATP,并计划将其引入 Android 等移动端...
- python遍历目录压缩文件夹然后在发送邮件_python目录操作之python遍历文件夹后将结果存储为xml...
- matlab处理图片建系,求MATLAB处理一张图片,把图片放入坐标系,建立类似于经纬度的网格...
- 添加面部跟踪和实时识别到您的Android应用程序
- 设计模式初探之模板方法(Template Method)
- php网页 安装插件,插件安装流程
- MATLAB App Designer GUI开发从0到1(二)
- Java IDE 的困惑
- web开发 java如何连接数据库并取得数据,实现 增,删,改,查
- userService 用户 会员 系统设计 v2 q224 .doc
- BA-风阀水阀执行器接线图
- linux 进程意外关闭,Webdriver异常:进程意外关闭,状态为1
- jQueryWEUI使用picker实现二级联动
- java企业进销存管理系统_Java实例学习——企业进销存管理系统(1)
- 人智导(二):启发式搜索
- [乐意黎]2016中级会计师考试《财务管理》真题及答案-第一批(9.10-9.11)
- vscode使用angular
- 微信小程序——云开发的安全规则
- 新手在IDEA如何创建一个Web项目
- 亲测源码小旋风蜘蛛池站群X8.51+自带30套模板
热门文章
- GNP/CMC(纳米石墨片/羧甲基纤维素钠)和GNP/rGO(纳米石墨片/还原氧化石墨烯)复合石墨膜-供应硫化锗玻璃/ 硒化镓GaSe/硫化镓GaS/碘化铬CrI3/鈣鈦礦/二硫化钛TiS2薄膜定制
- indesign页眉如何左右分布_InDesign排版技巧
- python图像轮廓识别_Python+OpenCV图像处理(十六)—— 轮廓发现
- 【WPS表格】数据透视表:修改行列字段顺序
- 温度指示报警电路设计报告
- ES6 之 Promise用法详解
- 智能硬件---智能硬件产品经理需要具备的知识
- 2022-08-26 JQuery(二)
- Day8——反转字符串、反转字符串||、替换空格、反转字符串里的单词、左旋字符串
- msp430发送pwm信号_使用MSP430G2单片机的PWM模块控制LED指示灯的亮度