Spring 发展

本文探讨了Java Web框架的发展历程,从Servlet+JSP到Struts2,再到Spring。Struts2解决了类型转化和封装、请求映射、响应构造等问题,并提供了自定义标签和拦截器。Spring作为轻量级的IoC和AOP容器,通过控制反转和面向切面编程简化了对象管理和事务处理。在SSH框架中,Spring扮演了管理容器的角色,降低了组件间的耦合度。
摘要由CSDN通过智能技术生成

想了解一个Spring发展,先来看看java Web框架发展。

java Web框架发展三步走:

  1. Servlet+JSP
  2. Struts2
  3. Spring MVC

1.Servlet+JSP

1.1 Servlet工作过程

这里写图片描述

Servlet的作用是接收浏览器传给服务端的请求(request),并将服务端处理完的响应(response)返回给用户的浏览器。

浏览器和服务端之间通过http协议进行沟通,其过程是浏览器根据用户的选择将相关信息按http协议报文的规范组装请求的http报文,报文通过网络传输到指定的服务器,服务器通过特定的web容器接收这个报文信息,例如:tomcat,jetty,jboss这样的web容器。

web容器会将http报文解析出来,如果是用户请求,最终解析出来的报文信息会用一个request对象存储起来,服务端使用这个request做完相应的处理后,服务端程序将结果信息封装到response对象里,然后将response对象交给web容器。

web容器则把这个response对象转变为http协议的报文,并将报文回传给浏览器,浏览器最后解析这个响应报文,将最终结果展示给用户。

Web容器创造了servlet接口,servlet接口就是开发人员自己实现业务逻辑的地方,程序员开发servlet就好比做填空题,而填空题的语境或者说上下文提示就是由request和response对象。

但是javaEE规范里的servlet接口很简单,就三个方法init,service和destory,但是这个接口太笼统,所以规范里还提供了一个HttpServlet类,这个类根据http请求类型提供了doGet,doPost等方法。

1.2 Servlet问题

servlet接口最大的特点就是根据http协议的特点进行定义,因此做servlet开发时候如果使用者对http协议特点不是特别熟悉,都会碰到或多或少令人迷惑的问题,特别是碰到一些复杂特殊的请求时候:例如文件上传,返回特殊的文件格式到浏览器,这时候使用servlet开发就不是很方便了,servlet开发还有个问题可能大家常常被忽视,就是请求的数据的类型转化。

http协议传输都是文本形式,到了web容器解析后也是文本类型,如果碰到货币,数字,日期这样的类型需要我们根据实际情况进行转化,如果页面传送的信息非常多,我们就不得不做大量类型转化,这种工作没有什么技术含量,是个体力活而且很容易导致程序错误。

同时java的企业开发都是围绕java bean进行,类型转化好的数据还要封装到对应的java bean里,这种转来转去的事情对于项目开发绝对不是什么好事情,所以古老的struts1为这种问题找到了一种解决方案,就是定义了一个DTO对象(数据传输对象),专门负责做这样的事情。不过到了struts2,整个替代servlet的action本身就是一个java bean。

2.Struts2

这里写图片描述

Struts2框架解决了以下问题:

  1. 解决类型转化和封装的问题
  2. 将每个请求对应一个方法
  3. 构造response对象
  4. struts2提供了自定义标签
  5. struts2的拦截器

Java的企业开发一个技术特点就是使用java bean进行的,struts2的特点之一就是它替代servlet的操作类就是一个典型的java bean。

2.1 解决类型转化和封装的问题

首先struts2框架将页面传输的数据进行类型转化和封装后,将请求信息封装到了这个java bean的属性里,这样我们开发web程序时候就省去了烦心的类型转化和封装的问题。

2.2 将每个请求对应一个方法

前面我讲到传统的servlet是根据http协议进行定义的,它会按你请求方式(post还是get方式)来处理用户的请求,但是对于一名程序开发人员而言,一个请求,具体到一个url,其实对于服务端而言就是服务端对外提供的一个功能,或者说是服务端对外的一个动作,如果我们使用servlet开发程序我们就得把http的动作转化为具体的业务动作,这就让程序开发变得繁琐,增强了开发的难度。

所以struts2替代servlet的java bean就屏蔽了servlet里http的请求方式和具体业务动作转化的问题,java bean里的每一个方法都可以和每一个url请求一一对应,这必然减轻了开发的难度问题。

2.3 构造response对象

Servlet另一个作用就是构造response对象,让页面获得正确的响应。其实现代的浏览器是一个多媒体工具,文字,图片,视屏等等东西都可以在浏览器里显示,资源的不同就会导致http响应报文的差别,如果我们使用servlet开发就要根据资源的不同在java程序里用硬编码的形式处理,这样的程序很难复用,而且如果程序员对某种资源的处理理解不到位,就会导致问题的出现。

struts2通过配置文件的形式将这样的逻辑从java程序里剥离出来,使用配置的方式进行统一管理,这个做法和spring的AOP方式类似,这样就让结果处理方式更加统一,更加利于管理,同时也提升了程序的健壮性以及降低了开发的难度。

2.4 struts2提供了自定义标签

Servlet在MVC开发模式里就是其中C层即控制层,控制层就像M模型层和V视图层的中间人,一个头向M层模型层看,一个头向V层视图层看。

模型层也是用java编写的,控制层也属于服务端语言开发,所以M层和C层的沟通没有天然的障碍,但是和V层视图层就不一样了,这是一个跨语言的沟通,对于浏览器,它只懂得html,javascript和css,浏览器是理解不了java这种语言的东西,但是要让服务端的东西能被浏览器理解接受,我们就必须得把服务端的响应信息放到页面里,因此就需要一个技术把java的信息转化到html页面里,这就是javaEE规范里提供了jsp技术。

jsp其实是一种服务端技术而非客户端技术,不过它看起来似乎更像html技术。

最早的jsp开发里都是直接将java代码写到页面里,这种坏处谁都知道,之后javaEE规范提供了自定义标签技术,使用一种类似html标签的方式来解析java代码。

struts2框架提供了一整套完整的自定义标签技术,这似乎听起来不算啥,但是它的作用非凡,因为自定义标签之所以叫自定义就是每个人都可以自己来定义,如果没有一个规范必然产生混乱,而且一套完善的自定义标签是个系统工程,一套完整的自定义标签相当于我们在自己定义一套新的开发语言,做程序的人听到这个一定就会明白开发一套完整的自定义标签的工作量和开发难度都是难以想象的,而且自定义标签都是和控制层紧密相连,其难度又会增加一个维度,所以struts2提供的自定义标签对于业务开发带来的将是质的飞越。

2.5 struts2的拦截器

Servlet里还有两个重要的技术:监听器和过滤器,对于监听器在web开发里使用的场景比较少,都是一些十分特别的情况才会使用,大部分web开发里可以忽略它的使用,我们用的最多的监听器可能就是对ServletContext创建和销毁的监听器,ServletContext是整个web应用的全局对象,它和Web应用的生命周期绑定在一起,因此使用这个监听器对Web应用的全局信息进行初始化和销毁操作,例如spring容器的初始化操作。

比较有意思的是过滤器,在struts2里有个拦截器,它们的作用相同都是用来拦截请求的,因为拦截器是struts2的特有功能,在struts2里使用拦截器自然比使用过滤器更顺手,其实拦截器所用的技术比过滤器更加先进,因为拦截器使用了反射技术,因此拦截器拦截的面更大,控制请求的能力更强,它能完成的任务也会更加的丰富多彩。

3.Spring

这里写图片描述

说完Servlet+jsp技术到Struts2技术的过渡,接下来谈谈Spring。

Spring的定义

Spring是什么?

Spring是J2EE应用程序框架,是轻量级的控制反转(IoC)和面向切面编程(AOP)的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器。

Spring可以单独使用,也可以和Struts2框架,Mybatis框架等组合使用。

Spring技术可以说是java企业开发里最重要的技术,而Spring这么大的框都是建立在IoC和AOP技术之上,只有深入理解了这两个技术我们才能明白为什么Spring这个框架能装的下那么多东西了。

3.1 控制反转(IoC)

这里写图片描述

首先是IoC,IoC技术第一个解释叫做控制反转,它还有个解释就是依赖注入,这两个名字很难从字面理解。

控制反转是,原来主动获取他所依赖的对象的引用,现在,变成被动获取他所依赖的对象的引用,这个责任的反转。

那么怎么将主动变为被动呢?

这就是借助“第三方”来统一管理所有的对象。这个“第三方”在Spring里叫IoC容器,对象的查找、定位和创建全部由IoC容器来管理。

控制反转的实现方法有两种类型,依赖注入(Dependency Injection,简称DI)和依赖查找(Dependency Lookup)。依赖注入应用比较广泛,Spring 就是采用依赖注入。

所谓依赖注入,就是由IoC容器在运行期间,动态地将某种依赖关系注入到对象之中。

IoC模式,系统中通过引入实现了IoC模式的IoC容器,即可由IoC容器来管理对象的生命周期、依赖关系等,从而使得应用程序的配置和依赖性规范与实际的应用程序代码分开。其中一个特点就是通过文本的配置文件进行应用程序组件间相互关系的配置,而不用重新修改并编译具体的代码。

3.2 面向切面编程(AOP)

这里写图片描述

AOP(Aspect-OrientedProgramming,面向方面编程),可以说是OOP(Object-Oriented Programing,面向对象编程)的补充和完善。OOP引入封装、继承和多态性等概念来建立一种对象层次结构,用以模拟公共行为的一个集合。当我们需要为分散的对象引入公共行为的时候,OOP则显得无能为力。也就是说,OOP允许你定义从上到下的关系,但并不适合定义从左到右的关系。

例如日志功能,日志代码往往水平地散布在所有对象层次中,而与它所散布到的对象的核心功能毫无关系。对于其他类型的代码,如安全性、异常处理和透明的持续性也是如此。这种散布在各处的无关的代码被称为横切(cross-cutting)代码,在OOP设计中,它导致了大量代码的重复,而不利于各个模块的重用。

而AOP技术则恰恰相反,它利用一种称为“横切”的技术,剖解开封装的对象内部,并将那些影响了多个类的公共行为封装到一个可重用模块,并将其名为“Aspect”,即方面。所谓“方面”,简单地说,就是将那些与业务无关,却为业务模块所共同调用的逻辑或责任封装起来,便于减少系统的重复代码,降低模块间的耦合度,并有利于未来的可操作性和可维护性。

AOP代表的是一个横向的关系,如果说“对象”是一个空心的圆柱体,其中封装的是对象的属性和行为;那么面向方面编程的方法,就仿佛一把利刃,将这些空心圆柱体剖开,以获得其内部的消息。而剖开的切面,也就是所谓的“方面”了。然后它又以巧夺天功的妙手将这些剖开的切面复原,不留痕迹。

使用“横切”技术,AOP把软件系统分为两个部分:核心关注点和横切关注点。业务处理的主要流程是核心关注点,与之关系不大的部分是横切关注点。横切关注点的一个特点是,他们经常发生在核心关注点的多处,而各处都基本相似。比如权限认证、日志、事务处理。Aop 的作用在于分离系统中的各种关注点,将核心关注点和横切关注点分离开来。正如Avanade公司的高级方案构架师Adam Magee所说,AOP的核心思想就是“将应用程序中的商业逻辑同对其提供支持的通用服务进行分离。”

实现AOP的技术,主要分为两大类:

一是采用动态代理技术,利用截取消息的方式,对该消息进行装饰,以取代原有对象行为的执行;

二是采用静态织入的方式,引入特定的语法创建“方面”,从而使得编译器可以在编译期间织入有关“方面”的代码。

3.3 Spring的事务

什么是事务?

事务就是对一系列的数据库操作(比如插入多条数据)进行统一的提交或回滚操作,如果插入成功,那么一起成功,如果中间有一条出现异常,那么回滚之前的所有操作。

为什么事务要管理?

这样可以防止出现脏数据,防止数据库数据出现问题。开发中为了避免这种情况一般都会进行事务管理。

JDBC中,是通过Connection对象进行事务管理的,默认是自动提交事务,可以手工将自动提交关闭,通过commit方法进行提交,rollback方法进行回滚,如果不提交,则数据不会真正的插入到数据库中。

Hibernate中则是通过Transaction进行事务管理,处理方法与JDBC中类似。

什么是Spring事务?

Spring中也有自己的事务管理机制,一般是使用TransactionMananger进行管理,可以通过Spring的注入完成此功能。

Spring只是控制数据库的事务提交和回滚,借助于java的反射机制,在事务控制的方法(通常是service层的方法)前后获取事务开启session,然后执行你的数据操作,如果你的方法内有异常被抛出,spring会捕获异常并回滚你在这个方法内所有的数据操作,如果成功则提交所有的数据,最后spring会帮你关闭需要关闭的东西。

所以spring想要做的是,要程序员专注于写逻辑,不需要关心数据库何时开启和关闭连接。

再说的通俗点儿:事务,对于一件事,对了就提交,错了就回滚,什么时候回滚,都是事务要做的事情。具体的操作由spring 配置来管理(同时你也可以脱离框架,自己写事务管理方法)。

AOP使用场景

AOP用来封装横切关注点,具体可以在下面的场景中使用:

  1. Authentication 权限
  2. Caching 缓存
  3. Context passing 内容传递
  4. Error handling 错误处理
  5. Lazy loading 懒加载
  6. Debugging  调试
  7. logging, tracing, profiling , monitoring 日志 跟踪 优化 校准
  8. Performance optimization 性能优化
  9. Persistence  持久化
  10. Resource pooling 资源池
  11. Synchronization 同步
  12. Transactions 事务

Spring中AOP应用

事务的处理:

在以往的JDBCTemplate中事务提交成功,异常处理都是通过Try/Catch 来完成。

而在Spring中,Spring容器集成了TransactionTemplate,它封装了所有对事务处理的功能,包括异常时事务回滚,操作成功时数据提交等复杂业务功能。

这都是由Spring容器来管理,大大减少了程序员的代码量,也对事务有了很好的管理控制。

Hibernate中也有对事务的管理,Hibernate中事务管理是通过SessionFactory创建和维护Session来完成。

而Spring对SessionFactory配置也进行了整合,不需要在通过hibernate.cfg.xml来对SessionaFactory进行设定。这样的话就可以很好的利用Sping对事务管理强大功能。避免了每次对数据操作都要现获得Session实例来启动事务/提交/回滚事务还有繁琐的Try/Catch操作。

这些也就是Spring中的AOP(面向切面编程)机制很好的应用。一方面使开发业务逻辑更清晰、专业分工更加容易进行。另一方面就是应用Spirng AOP隔离降低了程序的耦合性使我们可以在不同的应用中将各个切面结合起来使用大大提高了代码重用度。有利于代码重用,特别是Dao代码的重用。事务往往和业务规则紧密关联。当业务逻辑发生改变,意味着dao的大幅度改动。系统规模达到一定程度,修改风险相当大。

Spring的好处是不更改现有的dao,仅需对现有的service bean进行配置就达到事务效果了。同时,把事务统一在service层,系统结构更清晰。

SSH框架中Spring的角色

这里写图片描述

在SSH框架中Spring充当了管理容器的角色。

我们都知道Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL语句。

Struts是用来做应用层的,他它负责调用业务逻辑serivce层。

所以SSH框架的流程大致是:

Jsp页面–Struts(控制层)–Service(业务逻辑处理类)–Hibernate(Dao层)–数据库

struts负责控制Service(业务逻辑处理类),从而控制了Service的生命周期,这样层与层之间的依赖很强,属于耦合。

这时,使用spring框架就起到了控制Action对象(Strus中的)和Service类的作用,两者之间的关系就松散了,Spring的Ioc机制(控制反转和依赖注入)正是用在此处。

从上面我们不难看出:

从头到尾Action仅仅是充当了Service的控制工具,这些具体的业务方法是怎样实现的,他根本就不会管,也不会问,他只要知道这些业务实现类所提供的方法接口就可以了。

而在以往单独使用Struts框架的时候,所有的业务方法类的生命周期,甚至是一些业务流程都是由Action来控制的。层与层之间耦合性太紧密了,既降低了数据访问的效率又使业务逻辑看起来很复杂,代码量也很多。

Spring容器控制所有Action对象和业务逻辑类的生命周期,由于上层不再控制下层的生命周期,层与层之间实现了完全脱耦,使程序运行起来效率更高,维护起来也方便。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值