SpringMVC原理

  • Post author:
  • Post category:其他




1 什么是Spring MVC ?简单介绍下你对springMVC的理解?

Spring MVC是一个基于MVC架构的用来简化web应用程序开发的应用开发框架,它是Spring的一个模块,无需中间整合层来整合 ,它和Struts2一样都属于表现层的框架。

在web模型中,MVC是一种很流行的框架,通过把Model,View,Controller分离,把较为复杂的web应用分成逻辑清晰的几部分,简化开发,减少出错,方便组内开发人员之间的配合。


mvc详情



2 SpringMVC的流程?

在这里插入图片描述

(1)用户发送请求至前端控制器DispatcherServlet;

(2)DispatcherServlet收到请求后,调用HandlerMapping处理器映射器,请求获取Handler;

(3)处理器映射器根据请求url找到具体的处理器Handler,生成处理器对象及处理器拦截器(如果有则生成),一并返回给DispatcherServlet;

(4)DispatcherServlet 调用 HandlerAdapter处理器适配器,请求执行Handler;

(5)HandlerAdapter 经过适配调用 具体处理器进行处理业务逻辑;

(6)Handler执行完成返回ModelAndView;

(7)HandlerAdapter将Handler执行结果ModelAndView返回给DispatcherServlet;

(8)DispatcherServlet将ModelAndView传给ViewResolver视图解析器进行解析;

(9)ViewResolver解析后返回具体View;

(10)DispatcherServlet对View进行渲染视图(即将模型数据填充至视图中)

(11)DispatcherServlet响应用户。

前端控制器 DispatcherServlet:接收请求、响应结果,相当于转发器,有了DispatcherServlet就减少了其它组件之间的耦合度。

处理器映射器 HandlerMapping:根据请求的URL来查找Handler

处理器适配器HandlerAdapter:负责执行Handler

处理器 Handler:处理器,需要程序员开发

视图解析器ViewResolver:进行视图的解析,根据视图逻辑名将ModelAndView解析成真正的视图(view)

视图View:View是一个接口, 它的实现类支持不同的视图类型,如jsp,freemarker,pdf等等


详情



转发和重定向

(1)转发:在返回值前面

forward

(2)重定向:在返回值前面加

redirect:

  • 转发属于一次请求,重定向则是二次请求
  • 转发的地址栏不会改变,重定向的地址栏改变
  • 转发写跳转路径时不需要写工程名,重定向则需要加上项目工程名(eg:request.getContextPath + “/demo”)
  • 转发路径只能写项目内部资源的地址(eg:www.baidu.com不允许!),而重定向内外资源不限制
  • request域存取的值在转发(属于一次请求)中有效,重定向(二次请求)中无效



Springmvc的优点:

(1)可以支持各种视图技术,而不仅仅局限于JSP;

(2)与Spring框架集成(如IoC容器、AOP等);

(3)清晰的角色分配:前端控制器(dispatcherServlet) ,处理器映射器(handlerMapping),处理器适配器(HandlerAdapter),视图解析器(ViewResolver)。

(4) 支持各种请求资源的映射策略。



SpringMVC常用的注解有哪些?


@RequestMapping

:用于处理请求 url 映射的注解,可用于类或方法上。用于类上,则表示类中的所有响应请求的方法都是以该地址作为父路径。


@RequestBody

:注解实现接收http请求的json数据,将json转换为java对象。


@ResponseBody

:注解实现将conreoller方法返回对象转化为json对象响应给客户。



SpingMvc中的控制器的注解一般用哪个?有没有别的注解可以替代?

一般用

@Controller

注解,也可以使用

@RestController



@RestController

注解相当于

@ResponseBody + @Controller

,表示是表现层,除此之外,一般不用别的注解代替。



Spring MVC的异常处理 ?

可以将异常抛给Spring框架,由Spring框架来处理;我们只需要配置简单的异常处理器,在异常处理器中添视图页面即可。



SpringMvc的控制器是不是单例模式?如果是,有什么问题?怎么解决?

是单例模式,在多线程访问的时候有线程安全问题,解决方案是在控制器里面不能写可变状态量,如果需要使用这些可变状态,可以使用ThreadLocal机制解决,为每个线程单独生成一份变量副本,独立操作,互不影响。



ThreadLocal原理

通常情况下,我们创建的变量是可以被任何一个线程访问并修改的。如果想实现每一个线程都有自己的专属本地变量该如何解决呢? JDK 中提供的

ThreadLocal

类正是为了解决这样的问题。

ThreadLocal

类主要解决的就是让每个线程绑定自己的值,可以将

ThreadLocal

类形象的比喻成存放数据的盒子,盒子中可以存储每个线程的私有数据。

如果你创建了一个

ThreadLocal

变量,那么访问这个变量的每个线程都会有这个变量的本地副本,这也是

ThreadLocal

变量名的由来。他们可以使用

get()



set()

方法来获取默认值或将其值更改为当前线程所存的副本的值,从而避免了线程安全问题。



Thread

类源代码入手。

public class Thread implements Runnable {
 ......
//与此线程有关的ThreadLocal值。由ThreadLocal类维护
ThreadLocal.ThreadLocalMap threadLocals = null;

//与此线程有关的InheritableThreadLocal值。由InheritableThreadLocal类维护
ThreadLocal.ThreadLocalMap inheritableThreadLocals = null;
 ......
}

从上面

Thread

类 源代码可以看出

Thread

类中有一个

threadLocals

和 一个

inheritableThreadLocals

变量,它们都是

ThreadLocalMap

类型的变量,我们可以把

ThreadLocalMap

理解为

ThreadLocal

类实现的定制化的

HashMap

。默认情况下这两个变量都是 null,只有当前线程调用

ThreadLocal

类的

set



get

方法时才创建它们,实际上调用这两个方法的时候,我们调用的是

ThreadLocalMap

类对应的

get()



set()

方法。


ThreadLocal

类的

set()

方法

    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }
    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }

通过上面这些内容,我们足以通过猜测得出结论:最终的变量是放在了当前线程的

ThreadLocalMap

中,并不是存在

ThreadLocal

上,

ThreadLocal

可以理解为只是

ThreadLocalMap

的封装,传递了变量值。

ThrealLocal

类中可以通过

Thread.currentThread()

获取到当前线程对象后,直接通过

getMap(Thread t)

可以访问到该线程的

ThreadLocalMap

对象。

每个Thread中都具备一个

ThreadLocalMap

,而

ThreadLocalMap

可以存储以

ThreadLocal

为 key ,

Object

对象为 value 的键值对。

ThreadLocalMap(ThreadLocal<?> firstKey, Object firstValue) {
 ......
}

比如我们在同一个线程中声明了两个

ThreadLocal

对象的话,会使用

Thread

内部都是使用仅有那个

ThreadLocalMap

存放数据的,

ThreadLocalMap

的 key 就是

ThreadLocal

对象,value 就是

ThreadLocal

对象调用set方法设置的值。

在这里插入图片描述


ThreadLocalMap

是ThreadLocal的静态内部类。



SpringMvc中函数的返回值是什么?

返回值可以有很多类型,有String,ModelAndView。ModelAndView类把视图和数据都合并的一起的,但一般用String比较好。



版权声明:本文为luott_777原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。