首先我们来认识一下springmvc
SpringMVC 是类似于 Struts2 的一个 MVC 框架,用来替代servlet,是spring体系中一个web模块,设计优良,在实际开发中,接收浏览器的请求响应,对数据进行处理,然后返回页面进行显示,但是上手难度却比 Struts2 简单多了。而且由于 Struts2 所暴露出来的安全问题,SpringMVC 已经成为了大多数企业优先选择的框架。
探讨一下spring的工作流程(原理)
SpringMVC提供了总开关DispatcherServlet;请求处理映射器(Handler Mapping)和处理适配器(Handler Adapter),视图解析器(View Resolver)进行视图管理;动作处理器Controller接口(包含ModelAndView,以及处理请求响应对象request和response),配置灵活,支持文件上传,数据简单转化等强大功能。
DispatcherServlet的执行过程
先上图:
执行过程:
1、用户发起请求到前端控制器(DispatcherServlet),该控制器会过滤出哪些请求可以访问Servlet、哪些不能访问。就是url-pattern的作用,并且会加载springmvc.xml配置文件。
2、前端控制器会找到处理器映射器(HandlerMapping),通过HandlerMapping完成url到controller映射的组件,简单来说,就是将在springmvc.xml中配置的或者注解的url与对应的处理类找到并进行存储,用map<url,handler>这样的方式来存储。
3、HandlerMapping有了映射关系,并且找到url对应的处理器,HandlerMapping就会将其处理器(Handler)返回,在返回前,会加上很多拦截器。
4、DispatcherServlet拿到Handler后,找到HandlerAdapter(处理器适配器),通过它来访问处理器,并执行处理器。
执行处理器
5、处理器会返回一个ModelAndView对象给HandlerAdapter
6、通过HandlerAdapter将ModelAndView对象返回给前端控制器(DispatcherServlet)
7、前端控制器请求视图解析器(ViewResolver)去进行视图解析,根据逻辑视图名解析成真正的视图(jsp),其实就是将
ModelAndView对象中存放视图的名称进行查找,找到对应的页面形成视图对象
8、返回视图对象到前端控制器。
9、视图渲染,就是将ModelAndView对象中的数据放到request域中,用来让页面加载数据的。
通过第8步,通过名称找到了对应的页面,通过第10步,request域中有了所需要的数据,那么就能够进行视图渲染了。最后将其返回即可。
DispatcherServlet初始化过程
DispatcherServlet本质还是一个Servlet,Servlet的初始化要求我们实现init()方法,DispatcherServlet的init()方法是在HttpServletBean中实现的。
public final void init() throws ServletException {
if (logger.isDebugEnabled()) {
logger.debug("Initializing servlet '" + getServletName() + "'");
}
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) {
throw ex;
}
}
//最主要的操作都在这里面了
initServletBean();
}
protected void onRefresh(ApplicationContext context) {
initStrategies(context);
}
protected void initStrategies(ApplicationContext context) {
//初始化各大组件
initMultipartResolver(context);
initLocaleResolver(context);
initThemeResolver(context);
initHandlerMappings(context);
initHandlerAdapters(context);
initHandlerExceptionResolvers(context);
initRequestToViewNameTranslator(context);
initViewResolvers(context);
initFlashMapManager(context);
}
(重点)看源码很枯燥的,要不我们写一个吧
学好技术不是说用的很好,优秀的框架肯定有优秀的源码,要知道其所以然,最好还能模仿一二(看源码其实很无聊的,还想睡阔睡!!!∑(゚Д゚ノ)ノ远没有动手来的直接方便)。这不嫌弃看源码太头疼就动手写了个样子出来。使用的时候必须继承BaseConyroller,方便传参数。
项目源码地址:链接:https://pan.baidu.com/s/1AvxklLdlAos3-xzahtJqfQ 提取码:tf9k
欢迎各路大神为我指点不足!!!
萌新第一篇博客,有请神兽保佑:
* ┏┓ ┏┓+ +
* ┏┛┻━━━┛┻┓ + +
* ┃ ┃
* ┃ ━ ┃ ++ + + +
* ████━████ ┃+
* ┃ ┃ +
* ┃ ┻ ┃
* ┃ ┃ + +
* ┗━┓ ┏━┛
* ┃ ┃
* ┃ ┃ + + + +
* ┃ ┃ Code is far away from bug with the animal protecting
* ┃ ┃ + 神兽保佑,代码无 bug
* ┃ ┃
* ┃ ┃ +
* ┃ ┗━━━┓ + +
* ┃ ┣┓
* ┃ ┏┛
* ┗┓┓┏━┳┓┏┛ + + + +
* ┃┫┫ ┃┫┫
* ┗┻┛ ┗┻┛+ + + +