SpringMVC基础
MVC介绍:
MVC指的:Model View Controller, 是一种将业务逻辑、数据、界面显示分离的方法 .
Model:业务模型,模型对象通常负责在数据库存储数据、应用程序数据逻辑处理
View:视图显示,应用程序处理数据显示的部分
Controller:控制器,应用程序处理用户交互,从视图、用户输入中获取数据,向model中更新数据以实现数据逻辑处理。
相较于传统应用程序,可以让不同开发人员专注于自己所在的模块,提高效率和质量。后来又引申出MVP、MVVM等。
SpringMVC:
SpringMVC是一个实现了MVC的设计模式的java web框架,简化日常开发,同时他也是一个servlet系统,所以通过MVC的学习,能够很好的掌握MVC的设计模式以及基本的java web开发基础。
SpringMVC原理分析:
SpringMVC中的各层结构:
M层:Service组件与数据库Dao层,通过注解@Service声明
V层:一般指jsp,对界面进行渲染、显示的界面
C层:通过注解@Controller声明,与V层、Service连接,从V层获取用户输入、获取数据,向Service更新数据,操作业务数据处理,能够根据url获取具体请求
我们先从浏览器发出Http请求的第一步DispatcherServlet开始
DispatcherServlet:
首先说道HttpServlet,这个在本周三的文章中讲过Servlet入门,应该说很熟悉HttpServlet了,那么Servlet的生命周期:
Servlet生命周期包括三部分:
初始化:Web容器加载servlet,调用init()方法
处理请求:当请求到达时,运行其service()方法。service()自动派遣运行与请求相对应的doXXX(doGet或者doPost)方法。
销毁:服务结束,web容器会调用servlet的distroy()方法销毁servlet。
那么DispatcherServlet和HttpServlet是什么关系呢
可以看到,DispatcherServlet应该是HttpServlet的子类,也就是这个DispatcherServlet我们当初HttpServlet接收Http请求是一致的
那么,DispathcerServlet应该说是我们框架中的大哥。负责看门的小弟FrameworkServlet在收到Http请求之后,将所有请求都转向大哥的doService方法,告诉大哥,又有个不长眼的来找我们要资源啦!在FrameworkServlet中我们能够看到重写了doGet等方法,就是我们之前在Servlet中最重要的方法,用于处理对于请求的不同响应。
这些请求全部被导向一个processRequest的函数中,最终调用到我们DispatcherServlet的doService这个重写方法中
也就是说,不论请求发送是get、post、put还是delete,均会由FrameworkServlet来导向到DispatcherServlet中的doService中进行处理。
HandlerMapping
第二步是寻找映射,doService会导向doDispatch,然后由HandlerMapping寻找对应的控制器
能够看到通过HandlerMapping找到对应的能够处理该请求的处理器所在的类
之后会有一个叫做HandlerAdapter的对象
此步骤是我们的HandlerAdapter处理
这个时候,我们的测试用处理器到达了断点,从调用堆栈可以看出是经过了一个反射,那么也是由HandlerAdapter所处理,这是一个适配器模式的应用,这个方法会返回给doDispatcher一个ModelAndView对象
Holder for both Model and View in the web MVC framework. Note that these are entirely distinct. This class merely holds both to make it possible for a controller to return both model and view in a single return value.
Represents a model and view returned by a handler, to be resolved by a DispatcherServlet. The view can take the form of a String view name which will need to be resolved by a ViewResolver object; alternatively a View object can be specified directly. The model is a Map, allowing the use of multiple objects keyed by name.
这是api中所介绍的,用来保管model、view
那么我们去查看刚刚的结构,我们的控制器是直接返回了一个V层,可以看到被保存在了ModelAndView的view成员中。
所以整个过程由DisptcherServlet所控制,接收请求,找到控制器,拿到视图与模型,找到视图以及模型,将请求返回给浏览器。
这里的model指的是一个linkedhashmap,因此,我们的处理器除了可以返回jsp页面所在的文件路径,也可以返回一个model,也可以直接返回一个ModelAndView数据,而所使用的model则通过ModelAndView中的addObject()可以添加,在视图层可以使用EL表达式${key}进行取出。
常用注解:
@Service
定义了一个Service组件,进行业务逻辑处理、数据处理,与数据库接口进行交互
@Controller
控制器,从用户获取输入,获取数据通知Service进行业务处理,通知前端控制器显示视图
@Component
组件注解,在不方便区分Controller、Service的时候可以使用这个代替
@RequestMapping
请求映射,是HandlerMapping寻找映射中重要的一环,可以标注在类前、方法前,可以通过method设置请求类型是get还是put等
@ResponseBody
标注在类名前,告知前端控制器,本次返回将直接放入响应的body中,多用于ajax交互或者数据的传输,这样不会解析成视图而直接作为body传给浏览器
@Transactional
事务管理,事务:要么执行全部,要么一个不执行,可以用在方法前,在Service组件中,如果有些方法会较多次进行数据库的更新、插入、删除等操作,而某些异常可能会导致某些数据写入某些数据没有写入,而加了这个注解可以减少许多这种错误发生
@PathVariable
路径中,如果有想要的信息,比如/javaTree/1100,可以将RequestMapping写成如下形式:@RequestMapping(“/javaTree/{id}”),那么在参数列表中如此写:@PathVariable
Int id,那么,就能获得请求地址中id的值
@RequestParam
用于放在请求对象中,能够直接获得请求中传递过来的参数,一般也可不加,因为Request也会经过一个转换器将参数转换成需要的参数传进来
@Autowired
是一种函数,可以对成员变量、方法和构造函数进行标注,来完成自动装配的工作,@Autowired标注可以放在成员变量上,可以消除setter、getter,简化工作