造一个方形轮子文章目录:造一个方形的轮子
01、解决遗留问题
在上一篇《造一个方形的轮子5–数据库支持》的最后提出了一个问题,容器中的bean是多对一的关系,多个key对应的 都是同一个Bean 如果使用循环的方式,就至少会多一倍解析处理依赖注入问题,这个问题可以使用简单的方式处理掉。
BeansInitUtil.java 修改initDI()方法:
1 | /** |
简单解决了一下,添加一个已处理列表,处理之前先判断一下是否处理过,如果在已处理列表中则跳过。
02、Controller支持的整体思路
先来理一下,支持Controller的基本要求:
1、Controller本身也是容器中的Bean、因为需要做依赖注入
2、Controller能够支持路径映射,以处理不同的请求
3、需要有处理不同请求方式的能力,对应HTTP的GET/POST/PUT/DELETE
4、要有解析请求参数的能力,可以处理URL参数以及body参数(映射为JAVA VO类,方便使用)
5、可以格式化输出响应结果(先只支持一下json格式)
处理一个http请求的流程:
1、发起http请求
2、DispatcherServlet(自定义)统一截获请求
3、分析请求路径及请求类型
4、根据类型+路径获取Controller及方法
5、根据对应的方法参数列表从HttpRequest中获取并处理参数
6、反射调用对应的方法,获取返回结果
7、处理返回结果,设置对应的响应类型(application/json)
大概的流程就是这样,动手实现一下
03、改造容器类
开始之前先来改造一下原来的容器类,在之前的章节中,都是直接使用了一个HashMap做为Bean的容器,因为原来只在容器中保存一个Bean实例就可以了,但现在加入了Controller,需要一个http请求路径对应Bean实例的映射,原来的BeanMap就不能满足了(因为原来是使用的,接口、类、指定名称做的映射Key值),原来的Bean对象使用了一个BeanObject封装类,对应的现在为Controller对象添加一个ControllerObject类:
1 | package com.jisuye.core; |
这里记录的和BeanObject有很大区别,主要记录了被封装的对象实例,对应的执行方法以及参数列表,这里又引入了一个参数对象SquareParam.java:
1 | package com.jisuye.core; |
参数对象的功能,会在后边使用的地方详细说明,这里先来看改造后的容器类,为了做最小的改动,我添加了一个
BeansMap.java:
1 | package com.jisuye.core; |
这里的方法是为了兼容原来的HashMap容器添加的,这样把之前beansMap 的定义及参数类型,统一改成BeansMap就可以了。
04、添加相关注解
为了满足对Controller支持的需要,添加如下注解:
@Controller
1 | package com.jisuye.annotations; |
@GetMapping
1 | package com.jisuye.annotations; |
@PostMapping
1 | package com.jisuye.annotations; |
@PutMapping
1 | package com.jisuye.annotations; |
@DeleteMapping
1 | package com.jisuye.annotations; |
@RequestBody
1 | package com.jisuye.annotations; |
@RequestParam
1 | package com.jisuye.annotations; |
都是平常做JAVA Web开发经常使用的注解,不做过多解释了。
05、初始化Controller
接下来在做Bean初始化的时候添加初始化Controller功能,这样服务启动完毕后对应的Bean及Controller都初始化完毕可以直接使用了
项目启动过程先去初始化Bean,发现当前Bean是使用@Controller注解的,则调用初始化Controller方法,在initController方法中,执行过程如下:
1、获取当前Bean的所有方法,
2、循环判断是否有@GetMapping、@PostMapping、@PutMapping、@DeleteMapping注解,如果有则获取http请求类型及对应的方法映射路径
3、获取方法的参数列表,处理@RequestParam及@RequestBody注解
4、构造ControllerObject对象,并以
请求类型:类映射路径/方法映射路径
为key保存到BeansMap容器中
在原来的BeansInitUtil类中做如下修改(以下是代码片段只说明修改的地方,完整代码参见文末代码库分支):
1 | public class BeansInitUtil { |
06、小结
到目前为止,已经把添加Controller支持工作完成了一半了,现在已经可以初始化对应的Controller到容器中了,接下来要做的事就是把对应的请求和我们自己定义的Controller对应上就可以了,内容较多,就单起一篇写了。
本篇代码地址: https://github.com/iuv/square/tree/square6
本文链接: http://blog.jisuye.com/2019/07/17/square6/
版权声明: 本作品采用 知识共享署名-非商业性使用-相同方式共享 4.0 国际许可协议 进行许可。转载请注明出处!