SpringMVC的执行原理?
1、首先用户发送请求——>DispatcherServlet,前端控制器收到请求后自己不进行处理,而是委托给其他的解析器进行处理,作为统一访问点,进行全局的流程控制;
2、DispatcherServlet——>HandlerMapping, HandlerMapping 将会把请求映射为HandlerExecutionChain 对象(包含一个Handler 处理器(页面控制器)对象、多个HandlerInterceptor 拦截器)对象,通过这种策略模式,很容易添加新的映射策略;
3、DispatcherServlet——>HandlerAdapter,HandlerAdapter 将会把处理器包装为适配器,从而支持多种类型的处理器,即适配器设计模式的应用,从而很容易支持很多类型的处理器;
4、HandlerAdapter——>处理器功能处理方法的调用,HandlerAdapter 将会根据适配的结果调用真正的处理器的功能处理方法,完成功能处理;并返回一个ModelAndView 对象(包含模型数据、逻辑视图名);
5、ModelAndView的逻辑视图名——> ViewResolver, ViewResolver 将把逻辑视图名解析为具体的View,通过这种策略模式,很容易更换其他视图技术;
6、View——>渲染,View会根据传进来的Model模型数据进行渲染,此处的Model实际是一个Map数据结构,因此很容易支持其他视图技术;
7、返回控制权给DispatcherServlet,由DispatcherServlet返回响应给用户,到此一个流程结束。
SpringMVC如何保证Controller并发安全
Controller对象
默认是单例的
,实例化一个实例对象,多线程共享,所以线程不安全
。为了防止出现线程安全问题,在SpringMVC的Controller对象的属性中不能定义数据成员变量(排除Service)
,否则就要加同步锁。如果不小心在类中定义了类变量,那个这个类变量(静态变量)会被所有请求共享,可能会造成多个请求修改该变量的值,出现与预期结果不符合的异常。
1.类上添加@Scope(“prototype”)注解,这样每次请求调用的类都是重新生成的(影响效率)
2.使用ThreadLocal保存类变量,将类变量保存在线程的变量域中,让不同的请求隔离开来。