Spring概论-草稿0.8

Spring源起

简要说来,Spring 是一个开源的、为解决J2EE企业应用系统开发复杂性而创建的轻量级系统开发框架。这个框架源起于一位EJB(所谓J2EE重量级开发框架)的权威专家Rod JohnsonEJB的批评、反思与改进。这些批评、反思与改进构成了两本非常有名的著作的核心内容,这就是:《Expert One-on-One J2EE Design and Development》和《Expert One-on-One J2EE Development without EJB》。在这两本书中,Rod Johnson阐述了有关J2EE开发的方方面面的经验和设计,批评了EJB的种种不足(主要是太重的问题),然后通过对J2EE的改善设计而引申出了Spring框架,即作者为某一软件产品设计的系统开发框架,并介绍了Spring的基本原理。以这两本书中阐述的原理与引用的代码为基础,人们建立起了一个开源社区SpringSource,贡献给世界的伟大作品就是Spring框架。

Spring:定义

Spring是一种轻量级的J2EE应用程序开发框架,不过,更严格地讲它是针对Bean的生命周期进行管理的轻量级容器(Lightweight container),可以单独利用Spring构筑应用程序,也可以和StrutsWebwork等众多Web应用程序框架组合使用,并且可以与Swing等桌面应用框架组合使用。所以Spring并不仅仅只能应用在J2EE中,也能应用在桌面应用中,可以说只要是用到JAVA开发的地方,都可用上Spring

Spring的核心思想便是IoC/DI(控制反转/依赖注入)和AOP(面向方面的编程)Spring本身是一个轻量级容器,和EJB容器不同,Spring的组件就是普通的Java Bean(业务模型与业务逻辑都是以JavaBean的形式存在的),这使得单元测试可以不再依赖容器(EJB中的SessionBeanEntityBean必须在EJB容器中才能布署),编写更加容易。Spring负责管理所有的Java Bean组件,同样支持声明式的事务管理。我们只需要编写好Java Bean组件,然后将它们“装配”起来就可以了,组件的初始化和管理均由Spring完成,只需在配置文件中声明即可。这种方式最大的优点是各组件的“松耦合”,并且无需我们自己实现Singleton单件模式、工厂模式等来组装,也可以由Spring来统一管理对象关系的配置文件,而不会由于各个实现业务逻辑的程序员设计方法不同散落在各个角落(配置文件有的用XML来,有的用propertise属性文件,存放位置有的和编译后类字节码放到classes目录下,而有的放到WEB-INF目录下),增大了管理难度。

Spring:结构框图

 

 

Spring AOP

源代码级

元数据

AOP基础构件

Spring ORM

支持Hibernate

支持iBatis

支持JDO

Spring DAO

事务基础构件

JDBC支持

DAO支持

Spring Context

应用上下文环境

UI支持

验证

JNDI EJB支持和改造

Mail

Spring WEB

WEB应用上下文环境

多部分解析器

WEB应用

 

 

Spring WEB MVC

WEB MVC框架

WEB视图

JSP/Velocity

PDF/Export

Spring Core核心容器

应用支持集合

Bean容器

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 


每个模块的功能如下: 核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 IoC 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。

Spring 上下文环境:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDIEJB、电子邮件、国际化、校验和调度功能。   Spring AOP 通过配置管理特性,Spring AOP 模块直接将面向方面的编程功能集成到了 Spring 框架中。所以,可以很容易地使 Spring 框架管理的任何对象支持 AOPSpring AOP 模块为基于 Spring 的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。

Spring DAOJDBC DAO 抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写 的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。

Spring ORMSpring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDOHibernate iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。

Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。

Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSPVelocityTilesiText POI

Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 Web EJB)、独立应用程序、测试环境之间重用。

 

IoC/DI:“父母包办”就是好

什么叫IoC/DI(控制反转/依赖注入)?为什么它会成为Spring的核心内容,需要我们从面向对象的分析与设计说起。

我们设计出的软件模型越是接近现实世界,就越容易反映现实系统的运转,并且能更好适应现实系统的变化。不管你是采用面向过程的分析与设计还是面向对象的分析与设计,只要小心地研究现实世界中系统的运动规律,灵活地运用系统分析与设计的规则,都能达到上面的目标。但面向对象的分析与设计在于提供了一种机制使得系统分析与设计人员能更加方便快捷地达到这一目标。这种机制就是用对象来模拟现实世界中自主工作的实体,用对象之间的通讯来模拟实体之间的协作。由于用这种方式设计出来的软件系统与现实系统有一种同构的关系,带来的好处在于,一是人们只要理解了现实系统的结构与运作,也就能在一程度上理解了与之对应软件的体系结构和运作,反之亦然,这样就拉近了软件系统的使用者与设计者之间的“语义”差别,使得软件容易设计、容易理解、容易变更,也容易使用;二是,由于这种同构性,我们可以认为,现实世界中系统的变动如果需要从原定的5天延长到10天来进行调整,那也就同样可以预测软件系统的调整也只需要与之成线性正比的时间,从5小时延长到10小时,这种特性对软件的维护有非常重要的意义。

现实世界中的自主实体,比如医生,有其上班、治病、下班的工作周期,有其与之协作治病救人的其他自主实体,如护士。对象也一样有其生命周期,有其他与之协作以完成业务操作的对象,它们可以在计算机系统中被创建、协作以完成业务操作、销毁。如何管理对象的生存周期及找到协作对象,是面向对象分析、设计、编程中的重大问题。从某种意义上说,面向对象的分析与设计不外乎就是分析用以协作完成业务功能的对象是如何创建、协作、销毁的。

       JAVA语言而言,由于实现了高效的自动垃圾回收机制,对象的销毁非常简单,基本上不用操心,随用随丢,一切都有垃圾回收机制来保证对象能在合适的时机被销毁。

       而我们如何得到一个对象,这个对象如何知道与之协作的其他对象,如何相互通讯以共同完成业务操作,是面向对象系统分析与设计中的重大问题,关系到我们如何得到一个结构良好的软件设计,也就是“高内聚,低耦合”的软件系统。

       “高内聚”很容易理解,也就是对象作为自主实体的模拟物,应当尽量独立完成一定的功能,不需要过多调用其他对象提供的功能,与其他对象产生不必要的通讯联系。

       “低耦合”就稍微难一点,就是指对象之间的关系应当尽量松散,一个对象的变动,尽量不要影响与之协作的其他对象随之产生变动,也就是“牵一发动全身”的事情千万要在软件系统中中避免出现,不然就会陷入维护的泥坑,使得软件不能及时适应需求的变更,僵化落后,最终过早结束其生命周期。这是一个优秀软件设计开发人员不希望看到的结局。

       “高内聚”与“低耦合”是相辅相成的,实现了“高内聚”,对象之间协作关系就能做到最少,也就是协作完成业务操作的机会就少多了,在这种情况下,“耦合”的机会也就少多了,产生“高耦合”关系的风险也就少多了。

       要达到上面的目标,一是要做到良好的对象粒度划分,不要太粗,也不要太细。对象的粒度太粗,则一个对象可能就会做太多的事情,对象内部的业务流程就会太长、太复杂,与之对应的代码也会太长、太复杂,使得软件不容易理解与维护。而粒度太细,则会使得完成一个业务操作需要太多的协作对象,则过多的耦合不可避免,增大了“高耦合”情况出现的风险。

二是要为对象设计出良好的接口,对象之间通过接口了解对方,而不是真正的实体,要面向接口来进行设计与编程。

       下面来详细谈一下“耦合”的问题。

       对象如何创建并知道与之协作的其他对象,是判断一个系统“耦合”度的重要标准。既然对象是现实世界中自主实体在计算中的对应物,那我们也可以以现实世界中的自主实体及其协作来类比说明对象如何创建并知道与之协作的其他对象。

       我们以男孩追求女孩作为例子来类比一下。男孩如何知道女孩并追求她呢?不外乎下面这四种情况:

       一是自由恋爱;二是亲友介绍;三是父母包办;四是青梅竹马;

       自由恋爱就是男孩自己知道自己喜欢什么样的女孩,自己主动去追求;亲友介绍是男孩只知道亲友是哪谁,而亲友知道所有的女孩,男孩通过向亲友提出对女孩的要求,亲友就会找到合适的女孩介绍给他;父母包办是指父母已经在家庭中设计好了未来的儿媳妇位置,只需要把女孩放在这个位置上,男孩就会自动追求女孩;青梅竹马就是男孩一出生就女孩与之相伴,不用自己去找。

       那么,同理如下,对象是如何知道另外一对象并与之协作完成业务操作呢?不外乎下面这四种情况,对应了对象控制关系的四种TYPE类型:

       TYPE0new(新建); TYPE1service(服务);TYPE2 setter(设值子);TYPE3constructor(构造子)。

       new(新建)就是对象要与另外对象协作时,自己用new关键字得到一个,相当于两个对象“自由恋爱”;construtor(构造子)就是对象创建时,已经通过构造方法的以其参数形式传入与之协作的其他对象;service(服务)是指有服务存在于对象的上下文环境中,当对象需要协作对象时,通过这些服务提供的方法提出的要求并得到返回的对象,这些服务通常是以Singleton单件模式存在的一个或者一组对象;setter(设值子)是指对象已经有协作对象的属性及其setter方法,在适当的时候,通常是对象完成业务操作前,产生此对象的上下文环境会通过setter置入合适的协作对象。

       New是面象对象编程中对象耦合最基本的方法,同时也是产生“高耦合”系统的“最佳”手段。“自由恋爱”固然很好,直观自然,使用简单快速,但其却给我们的生活,同时也是给系统设计造成了很大困惑。如果男孩开始喜欢女孩A,星期一约她逛街,星期二约她看电影,但后来移情别恋,相当于软件系统中的需求变更吧,男孩又喜欢上女孩B,也想星期一约她逛街,星期二约她看电影,但一时疏忽,只改了星期一的日程表,而没有及时把女孩A在星期二日程表上更换下,那就成了星期一约女孩B逛街,星期二约女孩A看电影了,万一让人看见,那男孩岂不是被人认为是脚踏两只船。在软件系统中也是如此,如果业务需求发生变动,而在编程时却在代码中new的到处都是,散落到代码中的各个角落,对象间是“紧耦合”的,所造成的结果一是改动量大,维护效率低下;二是可能会由于疏漏,在有些地方找到并改正,在有些地方却没有,这样业务操作就会出错。

而其他三种,则提供“低耦合”系统的基本技术手段,也就是现在最流行的设计模式:IoC/DI(控制反转/依赖注入,Inversion of Control/Dependence Injection),有多种IoC/DI框架实现了上面的从TYPE1TYPE3的控制反转/依赖注入方式,而Spring实现了其中的TYPE2TYPE3,也就是setter(设值子)和constructor(构造子)。在Spring的日常应用中,更多是“父母包办”式的,也就是setter设值子方式。

       说到这里,控制反转/依赖注入也就很容易理解了,就是不主动创建对象,但是描述创建它们的方式。在代码中对象与对象不直接联系,也就是用new来产生对象,但在配置文件中描述哪一个对象需要其他对象协作,IoC/DI(控制反转/依赖注入)容器负责将这些联系在一起。

对象原来能主动创建其他对象,当然是主动控制了,但在Spring中,对象再没有主动的控制权了,只能被动接收其他对象,也就是控制反转了。依赖注入也是同理,原来对象能自己创建依赖于自己的其他对象,但现在没有这个权限了,被依赖的对象而是由外部容器准备齐全,直接使用就行,也就是依赖注入。

AOP:青出于蓝胜于蓝

AOP,面向方面的编程,是一种编程技术,它允许程序员对“横切关注点”的行为进行模块化。何谓“横切关注点”,就是跨越多个系统架构层次都要使用的功能点,也称之为“方面”,例如日志和事务管理。在典型的面向对象开发方式中,可能要将日志记录语句放在系统架构多层的Java对象中才能实现日志功能,因为无论是在视图层、控制层、模型层(业务逻辑层)都需要记录日志和事务管理,实现日志和事务管理功能的代码必然会散落到多个系统架构层中。也就是“紧耦合”了。

AOP 的核心是方面,也就是上面提到的日志和事务管理等可能会横跨多个系统架构层次的业务功能,AOP将那些方面封装到可重用的模块中,用模块化方式解决企业应用程序开发中的复杂问题。在 AOP 方式中,可以反过来将日志服务和开事务管理模块化,并以声明的方式将它们应用到需要这些服务的组件上。当然,优势就是 Java 对象并不需要知道日志服务和事务管理服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是“松耦合”的。

       就以事务管理为例,使用AOP提供的声明式事务管理,使得我们再也无需要用过程式的事务管理去通过硬编码相关事务处理API到业务逻辑代码中,来处理获得连接、关闭连接、事务提交和回滚等这些操作,也就是再也无需要我们在与事务相关的方法中处理大量的OpenCloseBeginTransactionEndTransactionRollBackTransactiontrycatchfinally代码。由此带来的优势非常明显:一是业务逻辑代码中无需关于关注事务逻辑,全部将给Spring通过AOP提供的声明式事务管理负责事务逻辑。Spring声明式事务让我们从复杂的事务处理中得到解脱。二是减轻了对特定事务处理框架的依赖程度,如果以后不想使用这种框架了,直接在AOP改一下相关声明就可以了。

       实现AOP的方法有很多种,功能最强大的AspectJ采用的是发明了一种的新语言,用自己的JAVA编译器,在JAVA字节码中嵌入了AOP所需要的代码,可以实现AOP的所有功能。但Spring没有这样做,它是采用了JDK1.3后提供的动态代理与反射技术来实现的。能实现方法级的AOP,但不能实现属性与final方法的AOP

       从本质上来说,AOP是一种对象增强技术,用间接的方式实现了JAVA所不支持的多继承。“方面”是指实现企业级应用所需要的对象的系统性功能,例如日志记录与事务管理,如果采取直接继承的方式,例如象EJB所做的那样,对象一是要带上一大堆与自己业务功能不相干的功能方法,这样就太“重”了;二是对象就与特定的体系架构“紧耦合”了,EJBSessionBeanEntityBean从就只能用到EJB环境中;三是运行这些对象需要启动提供整个企业级应用功能的容器,编程-测试-再编程的开发周期太长,影响开发效率,并且不能在容器外用Junit等方便的测试工具进行测试

       AOP目的就是让对象在不知晓的情况下,青出于蓝胜于蓝,为其增加多“方面”的功能。例如。

      

       事务的简介:

事务是一个最小的工作单元,不论成功与否都作为一个整体进行工作。

    不会有部分完成的事务。由于事务是由几个任务组成的,因此如果一个事务作为一个整体是成功的,则事务中的每个任务都必须成功。如果事务中有一部分失败,则整修事务失败。

 

当事务失败时,系统返回到事务开始前的状态。这个取消所有变化的过程称为“回滚”( rollback )。例如,如果一个事务成功更新了两个表,在更新第三个表时失败,则系统将两次更新恢复原状,并返回到原始的状态。

当事务处理系统创建事务时,将确保事务有某些特性。组件的开发者们假设事务的特性应该是一些不需要他们亲自管理的特性。这些特性称为ACID特性。

    ACID就是:原子性(Atomicity )、一致性( Consistency )、隔离性( Isolation)和持久性(Durabilily)

 

SHJAVA WEB开发双剑合璧

       经典的JAVA WEB应用框架即是SSH,它由Struts+Spring+Hiberante三个框架组成。

Struts MVC框架的好处:

Struts框架为Web应用提供了一个通用的框架,它把应用分成了三部分:视图、控制器、模型, 三个层各施其职,所以如果一旦哪一层的需求发生了变化,就只需要更改相应的层中的代码而不会影响到其它层中的代码。有利于开发中的分工 ,比如,在一个WEB应用中经常出现的新闻显示页面中,用户要求更改新闻内容的字体,则只需要更改一下MVC中的V视图,在JAVA WEB应用中,一般是指JSP页面,就可以了;如果用户要求的是不直接显示新闻内容,而是先显示新闻的摘要等信息,则只需要修改MVC中的C部分,在JAVA WEB应用中,一般指的是struts-config.xml文件。

一是有利于分工合作

MVC模式中,由于按层把系统开,那么就能更好的实现开发中的分工。网页设计人员可以进行开发视图层中的JSP,对业务熟悉的开发人员可开发业务模型,然后经由控制层装配起来。 

二是有利于组件的重用

分层后更有利于组件的重用。如业务模型层可独立成一个能完成某项业务操作的组件,不只能用到当前系统中,也能用到其他WEB系统中开发中,甚至可以用到基于SwingJAVA桌面应用程序开发框架中;

因此,使用StrutsMVC开发框架能够使我们的应用具有开发效率高、结构清晰、代码重用性高等优点

 

Hibernate ORM框架的好处:

在程序中我们用对象来描述真实世界,但在关系数据库还是数据的常用永久存储技术背景下,我们需要一种有效技术来完成对象到关系数据的转化(即对象的持久化,是图1中持久化层要做的)。而对象之间有许多关系数据无法表达的概念,如关联和继承等。如果直接通过JDBC来开发自己的持久化层很有可能影响项目的进度和持久层的可靠性,并严重影响代码的可维护性。因此,我们需要ORM框架来进行这一转化。而Hibernate是其中应用最广泛的成熟框架之一。

首先,ORM最大的优势。隐藏了数据访问细节,“封闭”的通用数据库交互,ORM的核心。他使得我们的通用数据库交互变得简单易行,并且完全不用考虑该死的SQL语句。快速开发,由此而来。

第二:ORM使我们持久化对象变得简单易行。如果没有ORM框架的,我们就需要将我们的对象模型转化为一条一条的SQL语句,通过直接连接关系数据库构造我们的数据库体系。而现在,基本上所有的ORM框架都提供了通过对象模型构造关系数据库结构的功能。

Struts与Hibernate的结合好处如下:

Struts虽然提供了一个MVC框架,但是其框架在对象持久化部分,也就是把对象保存到关系数据库中,并没有为我们提供什么技术实现,如果我们只是单纯的利用Struts框架进行Web 应用开发,那么在我们开发的业务逻辑处理中为持久化对象将势必会编写大量的JDBC硬编码,而且还要人为控制事务。Hibernate框架完全用面向对象的方式很好地实现了对持久化相关任务,使开发人员完全从JDBC硬编码中解放出来,完全用面向对象的思维来进行应用开发。因此,Struts加上Hibernate双剑合璧,能够很好地完成JAVA WEB应用开发。

 

SpringSH中间为什么要又插入一个S

但为什么要把Spring这个S横插到SH这个“完美”组合中呢?

SH框架开发,对于系统设计经验不足,不能灵活使用设计模式的人来说,直接用StrutsHibernate,会直接硬编码对象之间的联系,也就是前边提到的“自由恋爱”式设计,会造成Struts Action到业务逻辑JavaBean,再到Hiberante PO对象的业务处理,是一连串new对象式的代码,把这些对象紧紧耦合在一起。后果就是当需要变更业务需求时,需要在源文件中手工编码,然后再编译、发布;二是当一种框架不能满足需求时,要换其他框架时,例如,觉得Struts不能满足需要,想换成webworks,觉得Hibernate不好用,想换成iBatis,则需要对源代码大动手脚。因此,我们需要在这里把这些对象及其联系用Spring“父母包办”起来,。

因此,要回答为什么还要把Spring这个S插入到SH这对完美搭档的问题,可以一言以蔽之:“松耦合”。正如上面在对面向对象分析与设计中提到的,这是开发高质量、维护性好软件的必备法门,面向对象系统分析与设计给给软件开发带来的最大好处之一。

Springstruts加上hibernate带来的松耦合特性体现在两个方面:一是Spring的核心就是IoC/DI注入,它能使例如Hibernate PO,业务逻辑JavaBean,以及struts中的Action等组件,能以松耦合的方式结合在一块,而不是以硬编码的方式组合在一起(也就是上面提到的传统的在对象中以new方式生成另外对象,从而对象与对象之间的能通信协作),Spring通过配置文件管理类,通过控制反转/依赖注入的方式使对象之间相互知晓,当我们的系统业务逻辑发生改变时,只需改动配置文件即可。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值