tinySpring 分析笔记——IOC(1)
学习项目 Github 地址:code4craft/tiny-spring
step-1-container-register-and-get
使用 map 当作 bean 的容器,避免间接 new ,代替直接 new。
1.1 HelloWorldService.java
1 | public class HelloWorldService { |
简单不解释。
1.2 BeanDefinition.java
1 | public class BeanDefinition { |
最简单的 bean 文件,初始化时为 bean 赋值,getBean() 方法。
1.3 BeanFactory.java
1 | public class BeanFactory { |
最简单的容器——Map,具有插入和取值功能。
1.4 BeanFactoryTest.java【important】
1 | public class BeanFactoryTest { |
整体流程:
- 目标:执行 HelloWorldService 的 helloWorld 方法,但是不直接 new HelloWorldService()
- 所以先 new 一个 BeanFactory,然后 new 一个 BeanDefinition,在 BeanDefinition 中 new 一个 HelloWorldService(权宜之计)
- 将 BeanDefinition 插入 BeanFactory 的属性 Map 中
- 有需要时,从 BeanFactory 的 Map 中 get 到这个 BeanDefinition,然后执行 helloWorld 方法
- 结束
评价:曲线救国,意识有了,但操作垃圾
step-2-abstract-beanfactory-and-do-bean-initilizing-in-it
相比上一步,step 2 :
- BeanDefinition 类增加了
Class beanClass
和String beanClassName
属性,对应增加了 setter 和 getter 方法,重点关注 setBeanClassName 方法,这个方法加载名为“beanClassName”的类并执行其静态代码块,同时为属性 beanClass 赋值。
1 | public void setBeanClassName(String beanClassName) { |
2.1 BeanFactoryTest.java
1 | public class BeanFactoryTest { |
整体流程:
- 目标依旧:执行 HelloWorldService 的 helloWorld 方法,但是不直接 new HelloWorldService()
- 先 new 一个 BeanFactory,再 new 一个 BeanDefinition
- 但是,没有选择继续 new HelloWorldService,而是将 HelloWorldService 的全路径传入 setBeanClassName 方法中,由此得到这个类的 object(不是 instance)
- 在 beanFactory.registerBeanDefinition 的方法中,执行 beanDefinition.getBeanClass().newInstance() 方法,得到这个类的 instance。
- 然后从 BeanFactory 的 Map 中 get 到这个 BeanDefinition,然后执行 helloWorld 方法
- 结束
评价:将 bean 的创建放入工厂中,不错
step-3-inject-bean-with-property
相对上一步,step 3 为 bean 注入属性:
改变 HelloWorldService.java,增加属性
String text
及 setText()方法。在 BeanFactoryTest.java 中增加了一段设置 Property(即 text) 的代码,如下:
1 | // 2.定义 bean |
- 在生成 newInstance()的方法之后,增加一个
applyPropertyValues()
的方法。在这个方法中,将 HelloWorldService 中 name 为“text”的属性与 PropertyValues 中的同名属性“text”相匹配。然后将属性值赋进去。
1 | public class AutowireCapableBeanFactory extends AbstractBeanFactory { |
整体流程:
- 目标依旧:执行 HelloWorldService 的 helloWorld 方法,但是不直接 new HelloWorldService()。再加上一个小目标:为 HelloWorldService 的 text 属性赋值。
- 先 new 一个 BeanFactory,再 new 一个 BeanDefinition。
- 通过 Class.forName 得到 HelloWorldService 的 object(同时 将 bean 的
beanClass
和beanClassName
设置好了)。 - 将 PropertyValues 放入 BeanDefinition 的实例中。
- 得到 HelloWorldService 的 instance,将 PropertyValues 的属性值放入 instance 中,(将 bean 的
propertyValues
设置好了),在设置属性bean
,完整的 bean 就此产生,通过 getBean()方法就能够拿到 HelloWorldService 的 instance 了,就可以调用参数/执行方法了。 - 完毕。