文章内容输出来源:拉勾教育Java高薪训练营
文章目录
说明
写一个简易的仿SpringMVC的框架,可以支持简单的URL的映射处理
整体思路
实现的核心逻辑是在前端控制器DispatcherServlet中进行处理,分为两部分
-
初始化的准备工作
项目启动时,在DispatcherServlet的初始化方法中进行准备工作
1)实例化Bean:根据@Controller注解,实例化Controller类,放到IOC容器中管理
2)创建处理器Handler,放到处理器映射器HandlerMapping中管理:根据@RequestMapping获取请求方法,将URL与Method建立映射关系,放到映射器中 -
接收用户请求,进行解析处理,返回处理结果
用户在浏览器输入URL,发起请求,经过DispatcherServlet的请求方法
1)解析请求URL,从HandlerMapping查询到处理器Handler
2)解析请求参数,进行参数绑定
3)使用反射技术进行方法调用
4)获取方法调用的返回结果,进行视图的解析处理,返回给前端
实现过程
1. 创建web的maven项目
创建项目simple_mvc
2. 创建Controller注解
用于标识Controller类,在初始化时将其实例化放到IOC容器中管理,并获取其相关的Handler方法进行处理
- 支持在类上进行标识
@Documented
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Controller {
}
3. 创建RequestMapping注解
用于标识Handler,配置相应的请求URL
- 支持在类或者方法上进行标识
- 属性value表示请求的url,标识在类上表示根URL,标识在方法上表示请求方法的URL,两者组合为完整的用户请求URL
@Documented
@Target({
ElementType.TYPE,ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface RequestMapping {
String value() default "";
}
4. 创建处理器类Handler
- 增加
类、方法
的属性:Handler处理时能进行找到目标方法进行回调处理 - 增加
参数顺序映射Map
的属性:Handler处理时对应参数的解析、映射 - 增加
URL正则
的属性:查询Handler时可以根据URL进行正则匹配
public class Handler {
//controller类
private Object controller;
//controller类的请求方法
private Method method;
//url的正则
private Pattern pattern;
// 参数顺序,是为了进行参数绑定,key是参数名,value代表是第几个参数 <name,2>
private Map<String,Integer> paramIndexMapping;
//ignore setter/getter
}
5. 创建mvc的配置文件
配置文件为spring-mvc.properties
增加scanPackage
属性:在初始化时处理扫描包下的所有Controller类进行实例化等操作
scanPackage=controller类的扫描包名称
6. 创建前端控制器
前端控制器为DispatcherServlet
继承HttpServlet类,重载初始化方法init初始化方法、doGet和doPost的处理请求方法。doGet请求方法直接调用doPost请求方法,重点就放在doPost进行逻辑的编写
- 创建属性
properties
:存储解析mvc的配置文件中获取到的属性数据 - 创建属性
iocMap
:IOC容器,用于管理Controller的Bean - 创建属性
handlerMapping
:处理器映射器,用于管理Handler
public class DispatcherServlet extends HttpServlet {
//配置属性信息
private Properties properties = new Properties();
// ioc容器,管理controller注解标识的类,key是bean名称,value是实例对象
private Map<String,Object> iocMap = new HashMap<>();
//处理器映射,存储解析后的handler请求方法
private List<Handler> handlerMapping = new ArrayList<>();
//初始化方法,项目启动时进行初始化
@Override
public void init(ServletConfig config) throws ServletException {
}
//处理用户的GET请求
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
doPost(req,resp);
}
//处理用户的POST请求
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws IOException {
}
}
7. 前端控制器的初始化准备工作
1)获取mvc的配置文件路径,其中contextConfigLocation
是在web.xml
配置文件中的相应servlet
中获取
2)根据获取到的文件路径去解析文件,获取到的属性数据放到properties
中
3)扫描解析controller包下的所有类,进行实例化,放到IOC容器中管理
- 根据@Controller注解判断是否Controller类,如果是则进行实例化,放到iocMap
中
- iocMap
的key
是类名称(首字母小写)
4)初始化处理器映射器
- 遍历ioc容器中的所有controllerBean
- 判断controller类是否标识了RequestMapping
,则获取到URL
- 把method所有信息及url封装为一个Handler
- 获取方法的参数,计算方法的参数位置信息,其中HttpServletRequest
和HttpServletResponse
参数是需要特殊处理,其不是前端请求传递参数
- 将Handler
放到处理器映射器HandlerMapping
@Override
public void init(ServletConfig config) throws ServletException {
//1. 获取配置文件的路径
String contextConfigLocation = config.getInitParameter("contextConfigLocation");
//2. 加载配置文件的信息
doLoadConfig(contextConfigLocation);
//3. 获取controller类进行实例化,放到ioc容器中
doLoadBeans();
//4. 初始化处理器映射器
initHandlerMapping();
System.out.println("mvc 初始化完成....");
}