05|实现完整的IoC容器:构建工厂体系并添加容器事件
实现一个完整的 IoC 容器
增强扩展性
- 深入了解
- 翻译
- 解释
- 总结
本文深入讲解了如何构建一个完整的IoC容器,通过实现ApplicationContext接口和AbstractApplicationContext抽象类,丰富了IoC容器的功能。文章首先介绍了如何增强扩展性,通过新增接口ListableBeanFactory、ConfigurableBeanFactory、ConfigurableListableBeanFactory和EnvironmentCapable来使BeanFactory具有不同的特性,并且讲解了接口隔离原则在Spring框架中的应用。其次,详细讲解了环境因素的增加,包括PropertyResolver、EnvironmentCapable和Environment接口的实现。接着,展示了IoC引擎DefaultListableBeanFactory的实现,以及事件的发布与监听机制的完善,包括ApplicationEvent、ApplicationListener、ApplicationEventPublisher和ContextRefreshEvent的实现。通过实现ClassPathXmlApplicationContext类,演示了如何将其融入到ApplicationContext框架中。最后,总结了IoC容器的功能包括识别Bean定义、依赖注入、BeanFactory体系和容器应用上下文和事件发布。整体来看,本文对于想要深入理解IoC容器实现原理的读者具有很高的参考价值。
《手把手带你写一个 MiniSpring》,新⼈⾸单¥59
全部留言(19)
- 最新
- 精选
- KernelStone这一小结其实新增的内容不算多!只是对之前已有的代码进行结构调整。在项目中对DefaultListableBeanFactory生成UML结构图,再进行从上到下的梳理,这样会舒服一些。 0、【接口】BF,Bean工厂 1、【接口】SingletonBeanRegistry,单例Bean仓库 2、DefaultSingletonBeanRegistry,单例Bean仓库默认实现。提供了 1 注册列表 2 单例容器 3 依赖注入管理信息(两个Map,应该是依赖 & 被依赖) 3、【接口】BeanDefinitionRegistry【接口】ListableBF,这两个对照看差异。前者强调对BeanDefinition进行操作,后者强调是对List集合进行操作。 4、【接口】ConfigurableBF,Bean处理器(add & get,没有apply),以及管理依赖信息。 5、【接口】AutowireCapableBF,提供自动装配选项(No、byName、byType),并在初始化前后应用(apply)Bean处理器。 6、【集成接口】ConfigurableListableBF,无内容。 7、【抽象类】AbstractBF,主要是refresh(),invokeInitMethod(),createBean(),构造器注入和属性注入。 8、AbstractAutowireCapableBF,提供成员List<BeanPostProcessor>!也因此它可以通过该成员进行更多的bean处理器操作,即add、get、apply在此有了具体实现。 9、DefaultListableBF,其实没有啥,打开一看只Override了【接口】ListableBF中的4个方法,其余是默认继承。(即沿着类结构往上一堆,上面也说过了) 因此,这节课真没什么新东西,不过梳理这个新的工厂体系,倒是很麻烦。。
作者回复: 你这个总结真好!
2023-06-02归属地:广东6 - 马儿请教老师一下, 1.ClassPathXmlApplicationContext和AbstractApplicationContext都有beanFactoryPostProcessors属性,是不是重复了呢?感觉直接复用父类的这个属性和相关方法也是可以的。 2.AbstractAutowireCapableBeanFactory这个类中的beanPostProcessors属性写死了是AutowiredAnnotationBeanPostProcessor,不符合面向接口编程的风格。另外由于没有面向BeanPostProcessor导致DefaultListableBeanFactory需要再实现一遍 SingletonBeanRegistry 3.AbstractBeanFactory实现了BeanFactory又写了两个抽象方法applyBeanPostProcessorsBeforeInitialization和applyBeanPostProcessorAfterInitialization,这里为什么不直接实现AutowireCapableBeanFactory呢?
作者回复: 你很用心。 1,是重复了。 2,程序最后变成了BeanPostProcessor接口,你接着看。 3,后面有个beanfatory的继承关系图,你可以看看。
2023-03-23归属地:四川33 - CSY.老师我有个问题 ConfigurableBeanFactory 中的 dependentBeanMap 等几个方法为什么要使用同级继承在DefaultSingletonBeanRegistry实现,而不在AbstractBeanFactory等中实现?
作者回复: 并没有特别的理由,就是参考的Spring的做法。
2023-04-07归属地:河南1 - 啊良梓是我BeanDefinition mbd = this.getBeanDefinition(beanName); Class classToMatch = mbd.getClass(); 这里为什么是拿BeanDefinition的Class的?这样子没意义吧?或者我漏掉什么了? 前面存储Bean class 是 BeanDefinition的BeanName 才对.
作者回复: 你再仔细看代码,这个class代表的是哪个?
2023-04-03归属地:广东71 - Geek_513706老师,想提个建议,以后添加代码的时候能不能把添加到哪个包里面说清楚
作者回复: 这个建议已经接纳了,后面的文稿都带上了。完整代码要看Github上的。
2023-03-28归属地:内蒙古1 - 风轻扬思考题:Spring的bean作用域默认是单例的,就是我们的DefaultSingletonBeanRegistry类中持有的那个那个singletons的ConcurrentHashMap,每次获取bean之前,都会先从这个单例map中获取,获取不到才创建。 如果是多线程场景,有竞态条件存在的情况下,可以考虑将bean的作用域改为Prototype类型,对于Prototype类型的bean,Spring会为每次get请求都新建bean,所以每个请求获取到的bean是不一样的,这样就没有并发问题了 除了这两种作用域,还有另外四种作用域,我没怎么接触过,看了一下官方文档了解了一下。 文档地址:https://docs.spring.io/spring-framework/docs/5.3.27-SNAPSHOT/reference/html/core.html#beans-factory-scopes 遇到Spring的问题,可以多看看他们的文档,比搜索引擎强多了,写的很清晰 另外,我有一个问题,请教一下老师,ClassPathXmlApplicationContext为啥要实现BeanFactory?感觉他们两个不是一个体系里的吧,一个是上下文,一个是bean工厂
作者回复: 实现BeanFActory接口的原因是为了对外提供同样的API。
2023-03-24归属地:北京1 - Geek_03c08dBeanPostProcessor 接口 的 setFactory好像没有什么用
作者回复: 应该说是MiniSpring没有用到,写在这里,是为了软件的完整性。
2024-02-28归属地:广东 - Geek_03c08d希望老师回答 1. AbstractAutowireCapableBeanFactory 为什么不加一个继承AutowireCapableBeanFactory,这样就不用写抽象方法了 2. AbstractAutowireCapableBeanFactory 为什么是抽象的? 好像所有的功能都实现了
作者回复: 其实各种写法都可以,我这么做,主要是跟Spring本身保持一致。
2024-02-28归属地:广东 - Cornicione.ide一直提示DefaultListableBeanFactory没有实现ConfigurableBeanFactory的部分methods。看了github上的代码也是一样的问题。github上的源码ioc5真的是可以运行的吗?
作者回复: 刚才又从github上拿下来跑了一下,是没有问题的
2024-01-17归属地:美国 - 怕什么,抱紧我ConfigurableBeanFactory定义了getDependentBeans()方法; ConfigurableBeanFactory的实现类是DefaultListableBeanFactory,但是 DefaultListableBeanFactory没有实现getDependentBeans()方法,居然没有报错! 要是极客时间能发图,我肯定发一个图上来! 我到底错哪儿了!
作者回复: 看一下DefaultSingletonBeanRegistry
2023-05-30归属地:中国香港