SpringMVC 初始化流程分析

本文深入剖析SpringMVC的初始化流程,从HttpServletBean、FrameworkServlet到DispatcherServlet,揭示了DispatcherServlet作为SpringMVC核心如何负责调度工作,以及WebApplicationContext的创建过程。通过源码分析,帮助读者理解SpringMVC的工作原理。
摘要由CSDN通过智能技术生成

框架源码是我们 Coding 晋级中的必修课,SSM 应该算是小伙伴们日常接触最多的框架了,这其中 SpringMVC 初始化流程相对来说要简单一些,因此今天松哥就先来和大家分析一下 SpringMVC 初始化流程。

本文算是 SpringMVC 用法的一个进阶,如果小伙伴们对 SpringMVC 的基础用法还不熟悉,可以在公众号后台回复 ssm,有松哥录制的免费视频教程。

即使你没看过 SpringMVC 的源码,估计也听说过:DispatcherServlet 是 SpringMVC 的大脑,它负责整个 SpringMVC 的调度工作,是 SpringMVC 中最最核心的类,SpringMVC 整个顶层架构设计都体现在这里,所以搞明白 DispatcherServlet 的源码,基本上 SpringMVC 的工作原理也就了然于胸了。

然而 DispatcherServlet 继承自 FrameworkServlet,FrameworkServlet 又继承自 HttpServletBean,如下图:

因此我们的分析就从 HttpServletBean 开始。

1.HttpServletBean

​ ​HttpServletBean​ ​ 继承自 ​ ​HttpServlet​ ​,它负责将 ​ ​init-param​ ​ 中的参数注入到当前 ​ ​Servlet​ ​ 实例的属性中,同时也为子类提供了增加 ​ ​requiredProperties​ ​ 的能力,需要注意的是 ​ ​HttpServletBean​ ​ 并不依赖于 ​ ​Spring​ ​ 容器。

大家知道,HttpServlet 的初始化是从 init 方法开始的,所以我们就先从 HttpServletBean 的 init 方法开始看起:

@Override
public final void init() throws ServletException {
 // Set bean properties from init parameters.
 PropertyValues pvs = new ServletConfigPropertyValues(getServletConfig(), this.requiredProperties);
 if (!pvs.isEmpty()) {
  try {
   BeanWrapper bw = PropertyAccessorFactory.forBeanPropertyAccess(this);
   ResourceLoader resourceLoader = new ServletContextResourceLoader(getServletContext());
   bw.registerCustomEditor(Resource.class, new ResourceEditor(resourceLoader, getEnvironment()));
   initBeanWrapper(bw);
   bw.setPropertyValues(pvs, true);
  }
  catch (BeansException ex) {
   if (logger.isErrorEnabled()) {
    logger.error("Failed to set bean properties on servlet '" + getServletName() + "'", ex);
   }
   throw ex;
  }
 }
 // Let subclasses do whatever initialization they like.
 initServletBean();
}

在这个方法里,首先获取到 Servlet 的所有配置并转为 PropertyValues,然后通过 BeanWrapper 修改目标 Servlet 的相关属性。BeanWrapper 是 Spring 中提供一个工具,使用它可以修改一个对象的属性,像下面这样:

public class Main {
    public static void main(String[] args) {
        User user = new User();
        BeanWrapper beanWrapper = PropertyAccessorFactory.forBeanPropertyAccess(user);
        beanWrapper.setPropertyValue("username", "itboyhub");
        PropertyValue pv = new PropertyValue("address", "www.itboyhub.com");
        beanWrapper.setPropertyValue(pv);
        System.out.println("user = " + user);
    }
}

最终输出:

user = User{username='itboyhub', address='www.itboyhub.com'}

所以前面的 bw 实际上就代表当前 DispatcherServlet 对象。

通过 BeanWrapper 修改目标 Servlet 的相关属性时,有一个 initBeanWrapper 方法是空方法,开发者如有需要可以在子类中实现该方法,并且完成一些初始化操作。

属性配置完成后,最终调用 initServletBean 方法进行 Servlet 初始化,然而该方法也是一个空方法,在子类中实现。

这就是 HttpServletBean 所做的事情,比较简单,加载 Servlet 相关属性并设置给当前 Servlet 对象,然后调用 initServletBean 方法继续完成 Servlet 的初始化操作。

2.FrameworkServlet

从前面的介绍可知,FrameworkServlet 初始化的入口方法就是 initServletBean,因此我们就从 Framewor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值