01|原始IoC:如何通过BeanFactory实现原始版本的IoC容器?
IoC 容器
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何通过BeanFactory实现原始版本的IoC容器。作者从最简单的程序开始,一步步演化,最终实现了Spring框架的核心部分。IoC容器的作用是使用Bean容器管理业务对象,将创建对象与使用对象的业务代码解耦。文章提出了构建IoC容器的几个简单部件:Bean内存映像、XML reader、反射部件和Map。作者首先构建了BeanDefinition类,用于定义Bean的id和class。接着实现了ClassPathXmlApplicationContext类,通过解析XML文件获取Bean的配置信息,并利用反射创建Bean实例。最后,作者通过测试代码验证了容器的功能。文章强调了通过手写MiniSpring来学习Spring框架,尽量少依赖第三方包,以原始方式写程序,以便更好地理解底层原理。通过本文,读者可以了解到如何实现一个最原始的IoC容器,以及构建IoC容器的基本步骤和原理。文章还介绍了对ClassPathXmlApplicationContext进行解耦的优化扩展工作,包括定义BeansException、BeanFactory、Resource、ClassPathXmlResource和XmlBeanDefinitionReader等。通过这些步骤,读者可以了解如何构建一个简单的IoC容器,以及如何实现功能解耦,使容器的结构更加清晰明了,便于扩展适配更多的场景。整体而言,本文为读者提供了一个简单而具有基本功能的IoC容器种子,为后续添加更多功能奠定了基础。
《手把手带你写一个 MiniSpring》,新⼈⾸单¥59
全部留言(68)
- 最新
- 精选
- 6点无痛早起学习的和尚内容讲的很清晰,点赞。 这里有几个建议: 1. 每次代码设计之前,能否通过一个 UML 类图来表示,通过类图感觉更容易懂整个类与类之前的关系 2. 发现课程的内容还是有点偏向 Spring 那种感觉,就是有点类似:啊,Spring 是这样拆分几个类功能,那我们就这样拆分,这个方式感觉还是有点死板 感觉应该是:从一个设计者角度来讲,这样拆分更灵活,扩展性更强,叭叭叭等等,这样才能把读者带入进入课程,产生共鸣。 个人想法,欢迎交流,不知道是不是就我自己有这样感受,还是其他....
作者回复: 好建议,我会考虑考虑。 这个课程其实最早并不是教程,就是我自己手写Spring框架时的步骤,我当年用了29天时间,一天天搭建出来的。所以现在这个课程就是按照这个次序讲解的,可能是自己写的,觉得很自然。感谢你的建议。
2023-03-13归属地:北京35 - 姐姐从最初的简单ApplicationContext拆解成后面的复杂ApplicationContext,我理解起来还是有困难的,努力理解如下,大神勿喷:1 readxml方法从资源文件读取内容并存入beanDefinitions,这件事情有两个地方不确定,资源的来源不同、资源的格式不同,抽象的Resource的接口,它的不同子类从不同的来源读取,但是最终都是以Resource接口的形式提供给外部访问的,这样解决了第一个不确定来源的问题;但是resource接口中被迭代的object又是根据不同格式不同而不同的,element只是xml格式的,所以又定义了BeanDefinitionReader接口,它的不同子类可以读取不同格式的资源来形成beanDefinition 。 2 . instanceBeans方法取消了 。 3. getBean方法功能增强了,不仅是获得bean,对于未创建的bean还要创建bean 4 新的applicationContext负责组装,可以根据它的名字来体现它的组装功能,例如ClassPathXmlApplicationContext 它组装的Resource的实现类是ClassPathXmlResource ,然后因为是xml的,所以需要BeanDefinitionReader的实现类XmlBeanDefinitionReader来读取并注册进beanFactory,同时ApplicationContext也提供了getBean底层调用beanfactory的实现,提供了registerBeanDefinition 来向底层的beanFactory注册bean。5 beanFactory 提供了registerBeanDefinition和getBean接口,这样无论是applicationContext还是beanDefinitionReader都可以向它注册beanDefinition,只要向它注册了,就可以调用它的getBean方法,我一直很纠结为什么不是beanfactory调用不同的beanDefinitionReader,写完这些,好像有点理解了,这样beanfactory就很专注自己的getBean方法,别的组件要怎么注入,它都不管了。
作者回复: 你这个总结,是我见到的最详细的了,真用心。学完一遍必定大有收获。
2023-03-22归属地:浙江417 - adelyn请问会不会穿插讲一下用到的设计模式,单独学设计模式总是学不扎实,如果能讲到就太好了
作者回复: 会穿插讲到。确实如你所说,单独学设计模式总是会隔。
2023-03-13归属地:北京416 - 风轻扬说一下自己对思考题的理解。 控制反转。 控制:java对象创建的控制权。 反转:将java对象创建的控制权从程序员手中反转到IOC容器手中。 另外,说一下学完这一讲的感受。直白点说,很激动。我看过Spring这部分的源码,当时感觉挺简单的,并没有往深处想,其实忽略了“Spring为什么要这样写“的问题,现在感觉这才是源码的核心所在,突然有一点融会贯通的感觉,感觉很好。一直知道Spring的扩展性好,今天实实在在看到了。感谢老师传道解惑
作者回复: 赞!用心的程序员会爬上高峰。
2023-03-15归属地:北京13 - 未聞花名给老师个建议,可以点一下为什么类中要放这些属性和方法,突然抽到几个新类感觉过渡有点快,这样对之后自己去设计类也能举一反三,感觉自己平时设计不太好,如果自己实现起来的话比Spring的优雅可读性要差很多。 最后附上dom4j的maven依赖,希望帮助到其他人 ```java <!-- https://mvnrepository.com/artifact/dom4j/dom4j --> <dependency> <groupId>dom4j</groupId> <artifactId>dom4j</artifactId> <version>1.6.1</version> </dependency> ```
作者回复: 感谢感谢!
2023-03-18归属地:北京9 - 杨松老师这句话没理解呢:“我们用一个部件来对应 Bean 内存的映像”,文中5边型图片对应的其他4个都能理解
作者回复: 看的很细,感谢。这是书面语表达的理解问题,用我们程序员的口语来说就是“对一个Bean的定义,需要有一个类来对应。bean的定义可能是写在外部XML文件中的,类是运行时在内存中的,所以表达成Bean内存的映像”
2023-03-14归属地:辽宁36 - 周润发首先很感谢老师的课程,内容值得细品。 想请教一个问题,为什么在代码中更多使用全局变量而不在方法中使用成员变量呢?有些全局变量只在某个方法会用到,有什么特别的考虑吗?
作者回复: 想得细致。并没有特别考虑。这个课程的特点是逐步演化,开头只是个胚胎,不断重构发育,最后一步步变成Spring的样子,所以后面的程序跟前面的都会有变化的,稍安勿躁,你一点点看到最后。我希望带给大家的是Spring这个框架的变化定型的过程,而不是一开头就讲现在的Spring是什么样子。
2023-03-15归属地:浙江25 - UnknowngetClass().getClassLoader().getResource(filepath) 类加载器获取资源时 此处的filepath 需要放在resource目录里面(手动创建并标识类型为Resource root)
作者回复: 对的对的。你从Github上的ioc分支可以看到。
2023-03-15归属地:福建35 - C.ioc容器5天的版本手敲的,对应章节的代码:https://github.com/caozhenyuan/mini-spring.git 点击分支查看对应章节的代码。帮大家跟敲不迷路。
作者回复: 善事。记得给出原始出处。
2023-03-24归属地:江苏23 - 马儿以前的spring的源码都是散的,希望能通过这个课把这些只是串联起来。希望老师讲的时候可以讲一些设计模式,把创建类所在的包也希望能够说明一下,这样的话更方便大家学习了解类的用途和作用。
作者回复: 完整源码参见 https://github.com/YaleGuo/Minis。按照编辑的意见,在文稿中列出的代码是关键代码,不完整。这一部分可以看Github上的ioc分支。 后面会讲到设计模式,有好几位提到这个建议。
2023-03-13归属地:四川3