摘要:spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功完成了依赖的反转:从主类的对依赖的主动管理反转为了spring容器对依赖的全局控制。今天就带大家手写一个spring IOC容器。
本文分享自华为云社区《手把手教你写一个spring IOC容器》,原文作者:技术火炬手。
spring框架的基础核心和起点毫无疑问就是IOC,IOC作为spring容器提供的核心技术,成功完成了依赖的反转:从主类的对依赖的主动管理反转为了spring容器对依赖的全局控制。今天就带大家手写一个spring IOC容器。
第0步(准备工作):
(1)JDK1.8及java环境变量
(2)maven包及maven环境变量
(3)idea
第1步(创建项目,引入tomcat包)
PS:由于该项目的作用是模拟spring的部分功能,所以取名为spring
(1)创建好的项目内容如下图:
![](https://img.haomeiwen.com/i23297276/a8284b7e6c564007.jpg)
(2)pom文件的初始状态如下:
![](https://img.haomeiwen.com/i23297276/b75edfd1a47bf73b.jpg)
第2步:搭建主体框架
PS:一个正常的spring项目一般分为controller和service部分,此处暂时忽略数据库链接
![](https://img.haomeiwen.com/i23297276/752465993fcf2b68.jpg)
(1)其中,TestController实现功能,返回name+“Hello World!”,引用TestService
![](https://img.haomeiwen.com/i23297276/cd1484d6f367a534.jpg)
(2)而TestService和TestServiceImpl则分别实现功能
![](https://img.haomeiwen.com/i23297276/1288316f460494b0.jpg)
第3步:创建,并打上标签
PS:我们需要很多标签,如service,controller,还有autowired等
(1)创建各种标签(暂时创建这些标签,后面不够再加)
![](https://img.haomeiwen.com/i23297276/ff426b83e3914554.jpg)
(2)打上标签
![](https://img.haomeiwen.com/i23297276/6efb25179fd64da1.jpg)
![](https://img.haomeiwen.com/i23297276/deaebf89bb756d6c.jpg)
由于RequestMpping后面需要跟路径,所以此处需要重写其value()方法,如下:
![](https://img.haomeiwen.com/i23297276/d789038c0414fd44.jpg)
第4步:进入正题,创建一个DisPatcherServlet类,用于实现IOC容器功能
(1)DisPatcherServlet继承HttpServlet(注意添加依赖),并重写doGet,doPost方法
![](https://img.haomeiwen.com/i23297276/700d5bb3b542ce5d.jpg)
(2)创建一个doDispatcher方法,并被doPost引用
![](https://img.haomeiwen.com/i23297276/5620e5511a69b3c2.jpg)
第5步:初始化
(1)暂停实现doDispatcher,去重写初始化方法init,初始化共分为五大步骤,如下
![](https://img.haomeiwen.com/i23297276/8c4630e7f9d40642.jpg)
注意:顶端要加上属性类(Properties),且要resource中加application.properties,并加上scanPackage属性,内容为需扫描的根目录
![](https://img.haomeiwen.com/i23297276/3a776827f240fc17.jpg)
(2)加载配置文件实现,需要先配置一个web.xml,路径和内容如下:
路径:
![](https://img.haomeiwen.com/i23297276/a44b01cbaa78058b.jpg)
内容:
![](https://img.haomeiwen.com/i23297276/bd4f4b58e432c65f.jpg)
剩下的内容,大家应该能看懂的吧
![](https://img.haomeiwen.com/i23297276/91504f7ca35c05ed.jpg)
(3)下一步,使用递归,将所有class的路径存入一个集合(classPaths)里面
![](https://img.haomeiwen.com/i23297276/d54e031a4c1e8825.jpg)
(4)下一步,将打上了controller和service标签的类放入ioc容器中
![](https://img.haomeiwen.com/i23297276/aea3e1d9731829c6.jpg)
(5)下一步,注入(通过Autowired标签从IOC容器中获取实例对象并赋值)
![](https://img.haomeiwen.com/i23297276/9821d78f1276d38e.jpg)
(6)获取所有的RequestMapping内容,并写到一个对象集合中
第6步:回头实现doDisPatcher的步骤
![](https://img.haomeiwen.com/i23297276/4718c934fbff0ec5.jpg)
(1)首先,设定404(class notfound)
(2)后面一半,实现接口功能
PS1:判断url方法
PS2:根据url获取方法
PS3:获取方法下的所有参数
最后一步:执行tomcat
…
so,
(1)你以为以上的内容是对的嘛?
(2)你以为你能得到想要的结果吗?
太天真了!!!
如果你按照我说的方法去运行,恭喜你,得到的结果是not found!!!真正的挑战才刚刚开始:
第一,标签类的定义,如下,特别重要的是Target
![](https://img.haomeiwen.com/i23297276/f90487bdb18cc7ae.jpg)
还需要补充一个mapping
![](https://img.haomeiwen.com/i23297276/82c27a25de1cc5ae.jpg)
第二,TestController类中,RequestParam少了value属性,如果没有,则无法传值。
![](https://img.haomeiwen.com/i23297276/53468c1fb5e6f08a.jpg)
第三,那么参数初始化,是不是也有一点问题呢?注意这段代码,传参的名字应该和什么相关?
![](https://img.haomeiwen.com/i23297276/4a55194587cd6cf8.jpg)
好了 现在真的可以成功了~~~
![](https://img.haomeiwen.com/i23297276/b9a27da96e89329b.jpg)
看看结果吧。
![](https://img.haomeiwen.com/i23297276/7fb501dd60f99e28.jpg)
完结撒花~~~
网友评论