架构探险——搭建框架
Posted solverpeng
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了架构探险——搭建框架相关的知识,希望对你有一定的参考价值。
搭建轻量级Java Web框架
快速搭建开发框架
如何加载配置文件
如何实现一个简单的 IOC 容器
如何加载指定的类
如何初始化框架
*注解开发
目标:
打造一个轻量级的 MVC 框架,Controller 是MVC的核心,类似于 SpringMVC。
通过 Controller 注解来定义 Controller 类,在该类中,可以通过 Inject 注解定义一系列 Service 成员变量,这就是"依赖注入"。
此外有一系列的被 Action 注解所定义的方法(Action方法),在这些Action方法中,调用了 Service 成员变量的方法来完成具体的业务逻辑。
若返回 View 对象,则表示 JSP 页面;若返回 Data 对象,则表示一个 JSON 数据。
简单来说,就是一个 Controller 类包含多个 Action方法,可以返回 View 或 Data 对象,分别对应JSP页面或 JSON 数据。
@Controller 注解
@Service 注解
@Action 注解
@Inject 注解
View类:视图路径,模型数据
Data类:模型数据
Param类:封装有请求参数的对象
Request对象:封装请求信(请求方法和请求路径)
Handler对象:封装 Action信息(控制器类和处理方法)
核心:DispatchServlet:调用init方法时,初始化 Helper 类。service 方法中进行请求的获取与请求的处理
PropUtil→ConfigHelper:加载配置项,获取配置项定义的内容
ClassUtil→ClassHelper:获取指定包名下所有类,所有 Controller 类,所有 Service 类,所有 Bean 类。(CLASS_SET容器的概念)
ReflectionUtil→BeanHelper:创建了一个 Bean 容器,在 BeanMap中存放了 Bean类和 Bean实例的映射关系。(BEAN_MAP就是一个容器)
IocHelper:实现依赖注入
ControllerHelper:处理请求和请求处理方法之间的关系(ACTION_MAP也是一个容器)。
HelperLoader:四个Helper类通过一个入口程序来加载,实际上是加载他们的静态块。
基础:
定义框架配置项:
jdbc相关配置、项目基础包名、JSP基础路径、静态资源文件的基础路径
提供相关配置项常量
加载配置项,获取配置项定义的内容:由 PropUtil 提供支持(从当前线程来加载配置文件)→ ConfigHelper
开发类加载器:
开发一个类加载器来加载基础包名下的所有类,比如使用了某注解的类,或实现了某接口的类,再或者继承了某父类的所有子类。
ClassUtil工具类:提供与类操作的相关方法,
如
获取类加载器:只需要获取当前线程中的ClassLoader即可
加载类:public static Class<?> forName(String className, boolean initialize,ClassLoader loader)。其中 initialize 表示是否加载静态代码块。
获取指定包名下的所有类。
获取应用包名下的所有类、应用包名下的所有 Service 类,应用包名下的所有 Controller 类。
获取 带有 Controller 和 Service 类(Bean类,归 IOC 容器去管理)→ ClassHelper
实现 Bean 容器(由容器来创建对象←通过反射结合ClassHelper来实现)
ReflectionUtil(反射工具类):创建实例,调用方法,设置成员变量的值
BeanHelper:获取框架管理的 Bean 类,随后通过反射工具类来创建实例。将每次创建的对象都放入到一个静态的 Map<Class<?>, Object>类中。
实现依赖注入功能(通过容器对标注有某注解的成员变量进行实例化):
用 Inject 注解来实现对 Service 实例化。
具体实现:先通过BeanHelper获取所有的BeanMap结构,记录了类与对象的映射关系。然后遍历这个映射关系,分别取出 Bean 类与Bean实例,
进而通过反射获取类中所有的成员变量。继续遍历这些成员变量,看这些成员变量是否带有 Inject 注解,若带有该注解,则从 BeanMap 中,则从
BeanMap中根据Bean类取出Bean实例。最后通过 ReflectionUtil#setField 方法来修改当前成员变量的值。
加载Controller:
通过 ClassHelper,我们可以获取所有定义了Controller 注解的类,可以通过反射获取该类中所有带有Action注解的方法(简称“Action”)方法,
获取 Action 注解中的请求表达式,进而获取请求方法和请求路径,封装一个请求对象(Request),和处理对象(handler) ,最后将 Request和Handler
建立一个映射关系,放入一个 ActionMap中,并提供一个可根据请求方法与请求路径获取处理对象的方法。
ControllerHelper:封装一个 ActionMap,通过它存放Request和Handler之间的映射,然后通过 ClassHelper 来获取所有带有Controller注解的类,
接着遍历这些 Controller 类,从 Action 注解中提取 URL,最后初始化 Request 和 Handler之间的映射。
核心:
请求转发器(处理请求和响应):
处理所有请求,从HttpServletRequest对象中获取请求方法和请求路径。通过 ControllerHelper#getHandler方法来获取Handler对象。
拿到 Handler 对象后,我们可以方便地获取 Controller 的类,金额通过 BeanHelper.getBean 方法获取 Controller 的实例对象。
随后可以从 HttpServletRequest 对象中获取所有请求参数,并将其初始化到一个 Param 的对象中。
还可以从 Handler 对象中获取 Action 的方法返回值,该返回值可能有两种情况:
(1)若返回值是 View 类型的视图对象,则返回一个 JSP 页面。
(2)若返回值是 Data 类型的数据对象,则返回一个 JSON 数据。
总结:
通过 Controller 注解定义了 Controller类,通过Inject 注解来实现依赖注入,通过Action注解来定义Action方法。
通过一系列的 Helper 类来初始化 MVC 框架。通过 DispatchServlet 来处理所有的请求,根据请求方法和请求路径来调动具体的 Action 方法,判断
Action 方法的返回值,若为 View类型,则条状到 JSP 页面,若为 Data类型,则返回 JSON 数据。
以上是关于架构探险——搭建框架的主要内容,如果未能解决你的问题,请参考以下文章
EatBook-NO.3.EatBook.3.JavaArchitecture.2.001-《架构探险:从零开始写Java Web框架》-
前阿里P8架构师良心出版《架构探险轻量级微服务架构上下册》PDF