深度解读springMVC底层实现

使用JDK8 ,idea2018.2, maven3.5.4

使用XML 解析 + 反射来写一个springMVC框架:
如下思路实现;

首先需要一个前置控制器 DispatcherServlet,作为整个流程的核心,由它去调用其他组件,共同完成业务。主要组件有两个:
一是 Controller,调用其业务方法 Method,执行业务逻辑;
二是 ViewResolver 视图解析器,将业务方法的返回值解析为物理视图 + 模型数据,返回客户端。

bu

Spring MVC 的实现流程:

客户端请求被 DispatcherServlet(前端控制器)接收。
->根据 HandlerMapping 映射到 Handler。
->生成 Handler 和 HandlerInterceptor(如果有则生成)。
->Handler 和 HandlerInterceptor 以 HandlerExecutionChain 的形式一并返回给 DispatcherServlet。
->DispatcherServlet 通过 HandlerAdapter 调用 Handler 的方法做业务逻辑处理。
->返回一个 ModelAndView 对象给 DispatcherServlet。
->DispatcherServlet 将获取的 ModelAndView 对象传给 ViewResolver 视图解析器,将逻辑视图解析成物理视图 View。
->ViewResolver 返回一个 View 给 DispatcherServlet。
->DispatcherServlet 根据 View 进行视图渲染(将模型数据填充到视图中)。
->DispatcherServlet 将渲染后的视图响应给客户端。

分析:

HTTP 请求是通过注解找到对应的 Controller 对象…;
Controller 的 Method 也是通过注解与 HTTP 请求映射的;
使用map 当做 ioC 容器,完成储存所有参数与业务的class;
.

业务逻辑:

初始化工作完成,接下来处理 HTTP 请求,业务流程如下:
DispatcherServlet 接收请求,通过映射从 IoC 容器中获取对应的 Controller 对象;
根据映射获取 Controller 对象对应的 Method;
调用 Method,获取返回值;
将返回值传给视图解析器,返回物理视图;
完成页面跳转。

bu

doPost 方法处理 HTTP 请求:

解析 HTTP,分别得到 Controller 和 Method 对应的 URL
通过 URL 分别在 iocContainer 和 handlerMapping 中获取对应的 Controller 及 Method
使用反射调用 Method,执行业务方法,获取结果
结果传给 MyViewResolver 进行解析,返回真正的物理视图(JSP 页面)
完成 JSP 的页面跳转


项目结构如图

sdg

自定义注解:
@MyController
@MyRequestMapping

/**
 * @auther SyntacticSugar
 * @data 2018/11/13 0013下午 9:15
 */
@Target({
   ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyController {
   
    String value() default "";
}
/**
 *   自定义  @RequestMapping  注解
 */
@Target({
   ElementType.METHOD, ElementType.TYPE})
@Retention(RetentionPolicy.RUNTIME)
public @interface MyRequestMapping {
   
    String value() default "";
}

定义一个核心控制器MyDispatcherServlet ;

/**
 * @auther SyntacticSugar
 * @data 2018/11/13 0013下午 9:20
 * <p>
 * 创建控制器
 */
public class MyDispatcherServlet extends HttpServlet {
   
    //创建ioC  创建 handler存放容器

    private HashMap<String, Object> ioC = new HashMap<>();
    private HashMap<String, Method> handlerMapping = new HashMap<>();
    //自定义视图解析
    private MyViewResolver myViewResolver;

    @Override
    public void init(ServletConfig config) throws ServletException {
   
        // 把controller放到ioC中
        scanController(config);
        //初始化handler 映射
        initHandlerMapping();
        //加载视图解析器
        loadViewResolver(config);
    }

    @Override
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        this.doPost(req, resp);
    }

    @Override
    protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
   
        String handlerUri = req.getRequestURI().split
  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值