程序猿的日常——SpringMVC系统架构与流程回顾

web开发经历了很漫长的时间,在国内也快有十几年的时间了。从最开始的进程级到现在的MVC经历了很多的改进和优化,本篇就主要复习了解下Spring MVC相关的知识。

发展历程

第一阶段 CGI进程响应

这一阶段,服务器比较弱,请求也很简单,就是用户发一个请求,服务器接收后新建进程,然后返回结果。


这种方式一看代价就很大,每次都新建进程,很麻烦。

第二阶段 Servlet线程级别响应

Servlet结构跟上面差不多,只不过每次都只是新建一个线程,这样代价就小很多了。

Servlet的生命周期有四个阶段:

1 加载和实例化:启动Tomcat这种Servlet容器,容器会根据配置文件加载Servlet类,并通过new方法进行实例化
2 初始化:然后调用init()方法初始化,每个Servlet只会初始化一次,可以理解为单例模式
3 请求处理:当服务器接收请求后,接收请求的线程找到对应的Servlet,调用service()方法响应。因此会存在多个线程同时掉用一个Servlet实例的情况,因此这里会有线程安全问题的!
4 销毁:Tomcat关闭时,调用destroy()销毁容器。

那么整体的流程是这样的:

1 客户端发送请求,Tomcat服务器接收请求后,封装HttpRequest对象和HttpResponse对象
2 根据配置文件xml去查找匹配的servlet-name,并加载对应的servlet
3 如果之前没有加载过,那么加载并进行实例化和初始化;如果加载过,则直接调用service方法处理
4 把处理的结果封装到HttpResponse中返回

那么如何回答Serlet到底是不是线程安全呢?可以说它本身是无状态的,如果没有在里面自己新增一个什么count++的操作,就不会存在线程安全问题。

如果想要避免线程安全问题,可以采用下面的思路:

1 避免使用实例变量
2 避免使用非线程安全的集合
3 访问外部可写文件需要加锁

总结来说,这里只要注意Servlet的生命周期以及线程安全问题即可。

第三阶段 JSP+Model1

这个阶段引入了JSP技术,即Java Server Page,它是一种把HTML和Java混合在一起的技术语言。我记得我刚学习Java的时候,就是用这种JSP的技术,如果页面稍微复杂一点,代码就会特别混乱。

不过这种方式也引入了一种前后端分离开发的合作模式,即会有专门的开发静态页面的人,开发完后把页面交给后段程序猿,增量的开发Java相关的后端处理和数据展现相关的功能。

大体的流程是

1 用户发送请求给服务器,服务器对应的JSP页面接收到请求。
2 JSP会被编译成Servlet,模式就跟之前一样了
3 最后填充数据,返回即可。也就是说,它其实就是把之前页面视图的部分和Servlet的部分融合到一起而已。

现在基本上已经看不到这种技术模式了。

第四阶段 前后端分离+Spring MVC

现在大部分的模式就是这样的,只是在后段展现上略有不同。这种模式主要的关键是那个控制器,它负责任务的分发请求,以及数据的返回。

架构模型就如上面所示,不过在SpringMVC中,控制器有两种,一种是前端控制器,一种是应用控制器。

大致的流程为:

1 用户发送请求,前端控制器统一接收
2 然后根据不同的规则分发到对应的应用控制器,比如根据URL
3 应用控制器在调用逻辑代码处理
4 最后层层返回。

目前一般的公司,都是采用前后端分离的技术结构。
1 前端是Vue.js或者AngularJS再或者是JQuery,通过Http的方式发送到后端。
2 后端接收请求后按照一定的业务规则处理,然后把数据返回给前端。
3 前端通过JavaScript代码进行解析,浏览器渲染展现。

源码细节

经过上面的描述,对SpringMVC的整体流程应该有了大致的了解。但是经典的那句话,talk is cheap, show me your code。

这个Dispacther分发器是怎么实现的呢?其实它就是一个普通的Servlet而已,只不过Servlet拦截的请求时所有的请求而已:

<servlet>
    <servlet-name>test</servlet-name>
    <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
    <load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
    <servlet-name>test</servlet-name>
    <url-pattern>/</url-pattern>
</servlet-mapping>  

然后这个Servlet会调用doDispatch方法,主要的内容都在这里

protected void doService(HttpServletRequest request, HttpServletResponse response) throws Exception {
   省略代码
   try {
      doDispatch(request, response);
   }
   finally {
      省略代码
   }
}

doDispatch方法则包含了刚才描述的种种步骤:

protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
  省略
   try {
      省略
      try {
         // Determine handler for the current request.获得处理器映射
         mappedHandler = getHandler(processedRequest);
         // Determine handler adapter for the current request.获得适配器对象
         HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());
         // Actually invoke the handler.实际处理
         mv = ha.handle(processedRequest, response, mappedHandler.getHandler());
         //最后返回结果
      }
   }
}

常用的经验

1 如果时开发Restful风格的后端程序,即通过Http以及GET、POST、PUT、DELETE等进行数据的增删改查,那么可以直接使用@RestController注解

2 通常工程设计都会分为几层,Controller,Service,Mapper 如果有分层,可以用@Service@Autowired注解搭配自动注入

3 如果使用@Service,最好直接写上Service的名字,如@Service(value = "myService")不然如果你的名字是ABCService,默认的Service名字大小写会容易引发BUG,尤其是需要手动查找某个bean时。

4 一般为了让代码简洁,Controller参数列表可以封装一个JavaBean类,用来自动封装参数,是用的时候会方便得多。

本文转自博客园xingoo的博客,原文链接:程序猿的日常——SpringMVC系统架构与流程回顾,如需转载请自行联系原博主。

时间: 2024-07-28 14:31:04

程序猿的日常——SpringMVC系统架构与流程回顾的相关文章

程序猿的日常——Java中的集合列表

列表对于日常开发来说实在是太常见了,以至于很多开发者习惯性的用到数组,就来一个ArrayList,根本不做过多的思考.其实列表里面还是有很多玩法的,有时候玩不好,搞出来bug还得定位半天.所以这里就再啰嗦一下,整理下相关的内容. 基础知识 一般计算机相关的专业都应该学过数据结构,而很多的集合都是应用了经典的数据结构设计的.比如数组.栈.队列.链表.树等等,里面也会用到很多常见的查找或者排序算法,所以就先简单的回顾下. 数组 数组在c语言里面用的很广泛,刚开始学习的时候,整天的空指针和数组越界.后

程序猿的日常——Java基础之抽象类与接口、枚举、泛型

再次回顾这些基础内容,发现自己理解的又多了一点.对于一些之前很模糊的概念,渐渐的清晰起来. 抽象类与接口 抽象类通常是描述一些对象的通用方法和属性,并且默认实现一些功能,它不能被实例化.接口仅仅是描述一种方法的规约,即只能通过某几个方法来操作对象,它把内部的实现隐藏到实现类中,自己仅仅关注使用而已. 参数 抽象类 接口 默认的方法实现 它可以有默认的方法实现 接口完全是抽象的.它根本不存在方法的实现 实现 子类使用extends关键字来继承抽象类.如果子类不是抽象类的话,它需要提供抽象类中所有声

程序猿的日常——Java基础之clone、序列化、字符串、数组

其实Java还有很多其他的基础知识,在日常工作技术撕逼中也是经常被讨论的问题. 深克隆与浅克隆 在Java中创建对象有两种方式: 一种是new操作符,它创建了一个新的对象,并把对应的各个字段初始化成默认值: 另一种是用clone方法,基于已有的对象创建一个新的对象,此时会根据原有的对象各个字段赋值给新的对象. 如果对象的字段都是基础类型,没有什么问题,但是如果字段是对象,那么其实clone的时候复制的仅仅是对象的引用而已. 上面就是深克隆与浅克隆的区别. 在我们日常的开发中,如果涉及到克隆,就需

程序猿的日常——Java基础之equals与hashCode

equals和hashCode是我们日常开发最常使用的方法,但是因为一般都使用默认的规则,因此也很少会引起关注.不过了解他们的用途和设计的原则,还是会帮助我们更好的设计代码. equals equals是java很基础的一个问题,通常都会跟==来做比较.那么看看下面的问题: int a = 1; int b = 1; System.out.println(a==b);//true Integer a1 = new Integer(1); Integer a2 = new Integer(1);

Java程序员的日常——SpringMVC+Mybatis开发流程、推荐系统

今天大部分时间都在写业务代码,然后算是从无到有的配置了下spring与mybatis的集成. SpringMVC+Mybatis Web开发流程 配置数据源 在applicationContext.xml中引入数据源的配置: <context:component-scan base-package="com.test" ></context:component-scan> <context:property-placeholder location=&qu

这帮阿里程序猿在改变世界前 要先撼动歌坛

有一天我在内网闲逛,看见一个人气8000多的帖子,发帖人不是我,这谁抢了我的头条?我得进去看看... 原来是一群程序猿为了在阿里巴巴年会上一展歌喉,不比写BUG,居然要PK唱歌. 橙子默默想象了下我厂程序猿们放声高歌的画面,一句古诗就吟出来--"两岸猿声啼不住--" 这种事情,怎么能没有我,于是我啃着包子就去了. 场面有点恢弘啊,这配色!这晚霞! 这个人,这个腿形,这个头型,这个熟悉的条纹衫,这不是咱们的CTO行癫吗?!不进场站在外面拍照,难道你也没抢到票? 前方景色果然好!前面两排满

【聚能聊有奖话题】景甜华服下套秋裤被赞,身为程序猿的你靠什么熬过寒冬?

聚能聊有奖话题:https://yq.aliyun.com/roundtable/61801 请给博主[4号浮生递归]投一票,投完可以抽奖,天猫精灵在等你!https://yq.aliyun.com/promotion/430?id=people4 winter is coming 最近景甜华服下套秋裤的消息引起关注,有些人会奇怪,女明星在冬天的时候也穿的那么少,打扮的那么漂亮,她们不冷么?答案是冷!看看景甜参加活动时的照片,大冬天的裸漏双肩穿着裙子高跟鞋真漂亮,来看看幕后,秋裤是少不了的!景甜

系统架构师-请教:6年程序员的前途——系统分析师

问题描述 请教:6年程序员的前途--系统分析师 我到目前(2014年01月07日)已经做了1年半C.4年半C++的程序员,水平的话个人感觉比较一般,但自己对编程有爱好,最近考虑自己的前途规划,看到有人说程序员有2个发展线路,一条是技术路线,由程序员,经系统分析师.系统设计师直到架构设计师为归宿.而另一条是领导路线,由程序员,经开发小组负责人.工程 负责人,奋斗到项目经理.从我个人的情况来看,由于我性格比较内向,所以比较倾向于走技术路线. 我现在想提高自己,但要学的太多了,恳请各位指点迷津.我现在

这个22岁的程序猿可以打败比特币吗?

目前成长最快的虚拟货币网络以太坊(Ethereum)的创始人 Vitalik Buterin 试图用他的技术来打破所有规律. The DAO 攻击事件 柏林时间6月17日周五早上8:15,混乱突然间开始了. 德国科技公司Slock.it 的社区组织者 Griff Green 在公共聊天频道上发出"紧急警报!"的警告.紧接着,他又向一个大型投资的相关利益方发出请求:"请尽快对 Slock.it 成员进行数据挖掘!"(the DAO投资是他与公司共同启动的项目,此前该项