一 . 前言
作为开源软件,是有可能无法满足业务场景的.
这一篇主要从思想的角度来看 ,如何对开源框架进行深度的改造. 主要以 SpringMVC DispatchServlet 的定制为案例.
二. 定制的目的和方向
定制源码时一定要考虑升级和适配等多个问题 ,定制不是 fork , 好的定制行为可以伴随框架升级.
定制的目的
定制并不是秀操作的行为 , 如果框架本身就提供了完善的解决方案 , 能基本满足要求 , 就不要去深度定制一些功能 , 过多的配置会破坏框架的稳定性
定制的方向
对开源框架的修改主要可以分为以下几类 :
- 改源 : 对源头的参数进行修改
- 重写 : 重写核心处理类或者方法
- 插入 : 在链表中插入处理类
- 切面 : 对前后部分进行包围处理
三. 定制的方式
DispatchServlet 是 Spring-Web 的核心入口 , 也是对 Java Servlet 的封装实现 , 定制化的思路主要包括以下几个步骤 :
- S1 : 确定源码流程 , 读懂源码才能进行定制
- S2 : 分析外部处理流程和可重写的方法
- S3 : 对流程中可以插入的节点进行增强
DispatchServlet 核心处理流程
四. 细说不同节点的定制思路
4.1 节点一 : 请求参数的定制
进行这种定制的原因是由于很多开源框架中会通过 , 写个Demo演示一下 :
以上就是一个典型的案例 , 如果想定制认证类型 , 判断类型后进入处理逻辑.
- 通常这种场景下 , 不能修改实际处理类
- 通过 filter 的方式对请求参数进行改写
- 可以自行在外部进行复杂处理 , 最后组装成对于 Service 需要的模式
思路总结 : 请求参数的定制主要发生在主流程执行之前 ,通过拦截的方式去修改进入的参数 , 从而影响整个流程
4.2 节点二 : 定制处理类
上一种方式中 ,处理类是不可以定制的,而这一种处理类型则是通过定制Handler处理类来实现.
当然有些场景下 , 开源方会将这种流程隐藏起来 , 如SpringMVC这个 , 实际上是在中进行注册 , 在 中进行初始化.
如果没有文档 ,其实很难进行处理. 其实思路也很简单 :
- 对应处理器的configuration加载类
- 指定后缀如 Registry,Manager的工具类
- 通过Bean加载的类 , 如果提供了 add 方法也可以快速注册
不过这种方式还是保持在 Handler 外 进行包装处理. 通过AOP也可以实现相关的功能
4.4 节点四 : 改造 Service 类
最极端的方法之一 , 这种方法限制比较强 , 如果是Bean注入的还比较简单.例如一些基于Spring的开源功能框架.
如果是比较底层的Spring家族 , 很多本身就没有使用Bean注入 ,太底层反而不好去改写.
这种改造方式主要有两种思路 :
- 如果是Config注入的Bean , 进行覆盖
- 如果不可以覆盖 , , 通过优先级排序先执行自己的(重要)
常用的方式就是直接自定义 Config 进行自定义Bean的处理 , 运气好一把就可以成功.
很多场景下可能一把过不了 , 内部配置类的优先级会大于我们自己的 :
- 方案一 : spring.main.allow-bean-definition-overriding=true
- 方案二 : exclude 排除内部配置类 , 执行自己的配置类
- 方案三 : 控制配置类优先级,或者通过重写 spring.factories 修改排序
- 方案四 : 对 SpringIOC 内的Bean器进行处理 , 把里面的类覆盖掉 (没玩过,但是逻辑没毛病)
- 方案五 : 百度如果覆盖配置类 (方案很多,有点不记得了…)
方法很多 ,一般前2个就能处理 , 而且如果不是Spring家族体系的代码 ,一般也没这个问题
节点N : 直接重写 DispatchServlet
大牛的玩法 ,不就是重新写个SpringMVC~~
其实简单点说 ,就是把ManagerService进行重写,也有搞头
其他方向 :
- Java Assist 动态生成类
总结
对于开源框架的深度定制其实是无赖之举 , ,其实前后置处理器和链表中插入才是最合适的.不然别人出现个漏洞升级了 ,你代码就得完蛋
之前经历过一个产品就是对开源框架拉下源码进行深度定制.结果后期开源框架版本更新后 , 根本没办法跟上别人的节奏 ,对设计的思路破坏性改动 ,导致对后续拓展市场影响也很大.
文章知识点与官方知识档案匹配,可进一步学习相关知识Java技能树使用JDBC操作数据库数据库操作91536 人正在系统学习中
声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!