分类: Java
2010-12-26 15:01:20
Spring是什么?初接触的人会说Spring是个ioc容器。 这个答案只能获50分!!
Spring 框架是一个分层架构,由 7 个定义良好的模块组成。Spring 模块构建在核心容器之上,核心容器定义了创建、配置和管理 bean 的方式,如图 1 所示。
组成 Spring 框架的每个模块(或组件)都可以单独存在,或者与其他一个或多个模块联合实现。每个模块的功能如下:
1 :核心容器:核心容器提供 Spring 框架的基本功能。核心容器的主要组件是 BeanFactory,它是工厂模式的实现。BeanFactory 使用控制反转 (IOC) 模式将应用程序的配置和依赖性规范与实际的应用程序代码分开。
2 :Spring 上下文:Spring 上下文是一个配置文件,向 Spring 框架提供上下文信息。Spring 上下文包括企业服务,例如 JNDI、EJB、电子邮件、国际化、校验和调度功能。
3 :Spring AOP:通过配置管理特性,Spring AOP 模块直接将面向方面的编程功
能集成到了Spring 框架中。所以可以很容易地使 Spring 框架管理的任何对象支持AOP。Spring AOP 模块为基于Spring
的应用程序中的对象提供了事务管理服务。通过使用 Spring AOP,不用依赖 EJB 组件,就可以将声明性事务管理集成到应用程序中。
4:Spring DAO:JDBC
DAO
抽象层提供了有意义的异常层次结构,可用该结构来管理异常处理和不同数据库供应商抛出的错误消息。异常层次结构简化了错误处理,并且极大地降低了需要编写
的异常代码数量(例如打开和关闭连接)。Spring DAO 的面向 JDBC 的异常遵从通用的 DAO 异常层次结构。
5 :Spring ORM:Spring 框架插入了若干个 ORM 框架,从而提供了 ORM 的对象关系工具,其中包括 JDO、Hibernate 和 iBatis SQL Map。所有这些都遵从 Spring 的通用事务和 DAO 异常层次结构。
6 :Spring Web 模块:Web 上下文模块建立在应用程序上下文模块之上,为基于 Web 的应用程序提供了上下文。所以,Spring 框架支持与 Jakarta Struts 的集成。Web 模块还简化了处理多部分请求以及将请求参数绑定到域对象的工作。
7 :Spring MVC 框架:MVC 框架是一个全功能的构建 Web 应用程序的 MVC 实现。通过策略接口,MVC 框架变成为高度可配置的,MVC 容纳了大量视图技术,其中包括 JSP、Velocity、Tiles、iText(PDF) 和 POI(Excel)。
Spring 框架的功能可以用在任何 J2EE 服务器中,大多数功能也适用于不受管理的环境。Spring 的核心要点是:支持不绑定到特定 J2EE 服务的可重用业务和数据访问对象。毫无疑问,这样的对象可以在不同 J2EE 环境 (Web 或 EJB)、独立应用程序、测试环境之间重用。
IOC 和 AOP
控制反转模式(也称作依赖性介入)的基本概念是:不创建对象,但是描述创建它们的方式。在代码中不直接与对象和服务连接,但在配置文件中描述哪一个组件需要哪一项服务。容器 (在 Spring 框架中是 IOC 容器) 负责将这些联系在一起。
在典型的 IOC 场景中,容器创建了所有对象,并设置必要的属性将它们连接在一起,决定什么时间调用方法。下表列出了 IOC 的一个实现模式。
类型 1 服务需要实现专门的接口,通过接口,由对象提供这些服务,可以从对象查询依赖性(例如,需要的附加服务)
类型 2 通过 JavaBean 的属性(例如 setter 方法)分配依赖性
类型 3 依赖性以构造函数的形式提供,不以 JavaBean 属性的形式公开
Spring 框架的 IOC 容器采用类型 2 和类型3 实现。
面向方面的编程
面向方面的编程,即 AOP,是一种编程技术,它允许程序员对横切关注点或横切典型的职责分界线的行为(例如日志和事务管理)进行模块化。AOP 的核心构造是方面,它将那些影响多个类的行为封装到可重用的模块中。
AOP 和 IOC 是补充性的技术,它们都运用模块化方式解决企业应用程序开发中的复杂问题。在典型的面向对象开发方式中,可能要将日志记录语句放在所有方法和 Java 类中才能实现日志功能。在 AOP 方式中,可以反过来将日志服务模块化,并以声明的方式将它们应用到需要日志的组件上。当然,优势就是 Java 类不需要知道日志服务的存在,也不需要考虑相关的代码。所以,用 Spring AOP 编写的应用程序代码是松散耦合的。
AOP 的功能完全集成到了 Spring 事务管理、日志和其他各种特性的上下文中。
IOC 容器
Spring 设计的核心是 org.springframework.beans 包,它的设计目标是与 JavaBean 组件一起使用。这个包通常不是由用户直接使用,而是由服务器将其用作其他多数功能的底层中介。下一个最高级抽象是 BeanFactory 接口,它是工厂设计模式的实现,允许通过名称创建和检索对象。BeanFactory 也可以管理对象之间的关系。
BeanFactory 支持两个对象模型。
单态 模型提供了具有特定名称的对象的共享实例,可以在查询时对其进行检索。Singleton 是默认的也是最常用的对象模型。对于无状态服务对象很理想。
原型 模型确保每次检索都会创建单独的对象。在每个用户都需要自己的对象时,原型模型最适合。
bean 工厂的概念是 Spring 作为 IOC 容器的基础。IOC 将处理事情的责任从应用程序代码转移到框架。正如我将在下一个示例中演示的那样,Spring 框架使用 JavaBean 属性和配置数据来指出必须设置的依赖关系。
Spring是一个从web mvc一直到数据访问的完整程序结构体系。而且对于不同的人有不同的使用方法。让我一一道来。
最为人熟知的,Spring是一个ioc容器。这个对应Spring的org.springframework.beans包,
而且这是大家用的最多的功能。我们称为BeanFacotry。其基本原理说穿了很简单,读取一堆配置,侦测出各个bean的依赖关系。然后有两部分工
作,一部分是通过PropertyEditor,把配置文件中写的一些非bean数据绑定到每个bean的属性属性上(比如int,boolean,甚至
map类型的属性),还有一部分是建立bean之间的相互关系。当然这两部分是同时进行,没有先后。当初作者选用的是PropertyEditor,如果放到现在可能会选用ognl。btw,这个绑定机制在spring web mvc中也有用到 .。
如果只是使用ioc,只要知道配置文件怎么写就可以了。如果想自己写一个ioc容器可以看看这个包里的代码,特别是BeanDefinition和BeanFactory的设计非常精彩
其次Spring是一个ApplicationContext。现在Context这个词用的越来越烂,Spring的这个Context说穿了就是在BeanFactory基础上多了一些高级功能,包括 :
这些是一个大型程序常用的功能。不过,一旦你使用了spring的application提供的功能,那你的代码就和Spring再也脱离不了关系了。
以上是Spring的核心功能,Spring剩余的部分以ioc为手段,或以ioc为目的,向前端,后端,深层和周边范围扩展。说以ioc为手段是 因为有部分功能理论上是可以脱离Spring核心功能而使用,只是用了ioc后会简化很多工作量。以ioc为目的是因为还有一部分代码就是为了把其他库拉 进spring而设计。我们不妨……看过来,看过来……哦!哦!!
先说前端。Spring自带一个web
mvc框架。如果拿struts作比较的话,那么strust中的formbean,action和返回的formbean,依次对应着spring
mvc中的command,controllor和ModelAndView中的model。其实说穿了,现在的web
mvc的主要功能都很类似,提供一种机制把用户通过http提交的数据转换成比较容易使用的形式,顺便作一些校验。然后读取某个配置文件将这些数据传送到
一个控制器上。然后获取控制器返回的数据和视图名称,再找到对应的视图把这些数据和视图合并起来发回客户端。大家所比较的无非是哪个提供的附加功能多点
(比如谁的验证器又多又好),配置文件哪个写起来容易点,控制器尽量不要和业务功能过于耦合,作页面尽量好看点。基本功能不会有太大的差别。谁有能力和时
间的话,完全可以写个适配器,把其中的一套的某些功能适配到另一套上去。
spring的前端自有它的优势,能和ioc框架无缝整合,所有的配置统一被beanfactory读取。但是要用户spring
mvc除了要学习spring之外,还要学习一到两种页面显示技术。因为spring
mvc自己不带页面显示功能,默认情况下它使用的是jstl+jsp。至于spring的那套tag,我觉得纯粹是鸡肋,只是用来显示验证结果用的,并非
框架核心。用不用他的那套tag纯属个人爱好。
说句题外话,现在有不少web框架要和spring集成,大多数走的是配置ContextLoaderServlet,然后用
WebApplicationContextUtils.getWebApplicationContext的路子。其实说穿了也很简单。去看
org.springframework.web.context.ContextLoader的代码,会找到这两句
他就是把一个context放到了servletContext里去了。然后大家再从servletContext里拿。这样只能从web框架单向 引用到managed bean,而bean用不到web里的对象。除非这些web框架能够在运行时动态向sping的ioc容器里添加自己创建的对象或者直接让spring协 助创建。
转回话题
向后端是指spring同一些DAO框架进行集成。这方面spring更多的是在搭桥。比如hibernate的
LocalSessionFactoryBean。这些桥搭起来后,我们可以很方便的从spring中访问这些dao框架。而这些框架对spring可以
说是一无所知。此外由于dao代码的复杂性和重复性,spring还提供了一些template,来降低开发人员的工作量,简化代码。spring的这些
功能可以说是大部分的体力活和小部分的脑力劳动。不过我们还是要感谢这些牛人们,他们是虽然不是“加拿大gcd员”,但是为了帮助中国的程序开发事业,即
使未受“加拿大gcd和美国gcd的派遣”,还是把spring框架不远万里的带到中国。
向深层方向发展是指spring的aop和transaction功能。这些功能的基本原理就不说了。虽然未必是spring独有的,但这些实现都
是spring作者亲自设计的。可以说是他们的“自主知识产权”。我可不希望有xx人看到这些代码拿倒自己的公司然后打上copyright。我肯定会找
这种人拼命的 。这些功能其实和ioc一点关系都没有。而且spring的reference里也说可以"programmatically"的。比如
这些功能处于不用ioc也可以跑,不过用了ioc用起来更方便的位置。如果谁在这方面有兴趣也可以翻翻spring代码。比如要写一个简单的事务管 理器,就可以去看spring的各种TransactionManager的实现。当然真正的回滚递交机制的实现这些代码帮不上忙的。
最后说说周边扩散。这表现在两方面,一方面是spring内部所集成框架和类库的数量越来越多。spring最早的版本中就包含quartz的集
成,后来加上了jms,这些可以说是和spring中的其他部分完全不相干的东西。此外越来越多的项目在向spring靠拢或者使用spring作为项目
内核,比如开源的jms服务器active mq,web中用到的valuelist。
以下是回复 :
Spring的附属产品确实越来越多了,Spring虽然号称non-intrusive,也只是Spring core能做到。剩下的部件只要你越用越深入,到最后Spring完全就渗入到敌方组织内部了,真是高明啊
错了..如果你只是觉得每个MVC都这样就很好笑.如果再把他们连起来,就会知道MVC的发展史是怎么样的.这是一种思想上的进步.
Spring2.0的发布恐怕算得上2006年Java社区的一件大事了。在Spring2.0发布附带的文档里面对2.0新特性做了概要的介绍,2.0的新特性是自然是我们最关注的方面:
一、Spring的XML配置引入XML Schema语法简化配置
在Spring1.x系列中,bean的配置文件使用DTD,没有namespace的分隔。2.0的一个非常大的改进是引入了XML Schema的namespace,因而可以将bean的配置文件做大幅度的简化。这些简化包括了对bean属性的各种简化,AOP配置的简化,事务配置 的简化,JNDI配置的简化等方面。当然,在简化配置的同时,新的XML Schema实际上引入了更多的XML语法,因此使用一个支持XML Schema的XML Editor就显得非常必要了,例如Eclipse WTP就可以提供Schema的语法自动提示和校验功能。
Spring1.x的bean配置文件逐渐复杂烦琐化,是Spring历来被人所垢病的主要问题之一。在Spring2.0里面XML Schema语法的配置可以在相当程度上降低配置文件的复杂程度和烦琐程度,可以视为Spring的重大改进之一。但是我们也必须看到XML Schema并没有从根源上面解决XML配置复杂的问题,而只是减轻。
将所有的bean之间的依赖关系,组装关系统统使用XML来描述,本身就会导致XML阅读和修改一定的困难。并且用XML配置本身无法直接进行单元测试来验证依赖关系。因此,当bean之间关系越复杂的时候,XML配置文件本身的维护也是一个负担。
我个人比较期待未来的Spring能够使用脚本语言来编写和组装bean之间的关系,这样组装脚本本身也是可测试的,而且脚本的描述能力要远远好于XML配置文件,同时编写和维护起来也比XML轻松。
二、提供了request和session范围的bean
引入request scope和session scope的bean,我感觉是把双刃剑。对于普通的Java Web框架应用来说,和Servlet容器相关的操作应该限制在Web层,对于业务层来说,不应该涉及request和session的scope,否则 业务层代码无法脱离Servlet容器进行单元测试。对于使用Webwork/Struts框架的用户来说,恐怕不太会使用该特性,另外根据我的理解,也 许request/session scope的bean也是为了提供给Spring MVC的Controller使用的。
除此之外,对于AJAX Web Service调用来说,这一特性反而是很有用处的。对于这种应用场景,JS通过AJAX调用,抛开Web层框架,直接访问业务层bean,这个时候就需要提供request/session scope的bean了。
三、集成AspectJ,可以管理容器外对象,提供了领域模型的依赖注入
通常由Hibernate管理的持久化对象PO,并不是由Spring容器初始化的,往往是用户自己new出来,或者通过find,load方法创建的,其结果就是Spring容器无法对这种容器外创建的对象进行bean依赖关系注入。
在Spring2.0中,可以使用AspectJ对领域模型进行静态织入,这样当该领域模型在容器外被创建的时候,会产生对容器的回调,进行依赖关系的注入。
Spring2.0提供的这一特性,确保了Martin Folwer的Rich Domain Object的可行性,这一特性的提供恐怕会对未来很多Java系统的设计产生相当深远的影响。
其实针对Rich Domain Object更进一步,如果将DAO功能作为Domain Object的抽象父类,那么持久化对象PO就会集PO,DAO,Service对象于一身,整个业务层,持久层完全合并为一个对象,通过这种方式进行框 架简化得到的结果就是,高度类似于ruby on rails的full-stack的MVC框架。
四、JPA支持
这一点其实没有什么可点评的,提供JPA支持本来就是理所应当之事。
五、JDBC的NamedParameterJdbcTemplate
NamedParameterJdbcTemplate我认为意义非凡,为JDBC查询提供了带命名参数的占位符,而不止是JDBC自己的“?”,这样使用JDBC的时候,也可以很容易的构造出来带占位符的动态条件查询,而不是参数值带入方式的拼接SQL字符串了。
六、Spring Web MVC功能的大幅度扩充
看的出来,在Spring2.0里面 Web MVC功能大幅度扩充,过去不提供的UI Taglib也终于提供了,配置文件也进行了必要的简化。虽然Spring MVC从框架设计角度来说远远不如Webwork那么有创意,但是也是一步一个脚印的改进,再配合上各种外围框架例如Spring Webflow等的支持,可以预见Spring MVC会成长为Webwork的劲敌。
七、支持动态语言ruby,groovy,beanshell
动态语言支持目前看来还比较简单,不够强大,但是表明了Spring的一个态度,其实我个人希望Spring能够加强这方面支持,甚至大胆一点,提供用动态脚本语言编写的bean组装配置。
八、异步JMS支持,JMX支持,JCA支持的功能完善
Spring2.0自身提供了两类简单的JMS Containter,此外还提供了外部JMS Server的接口,另外JMX功能的支持,JCA功能的支持都在进一步的完善过程中。
Spring2.0在这几个方面的功能支持不是那么引入注目,毕竟普通Java Web应用很少使用这些方面。但是Spring提供这些功能的完善支持意义却很深远,因为这些功能都是J2EE规范所要求提供的功能,也是传统应用服务器 厂商相对比Java开源框架的传统优势项目。一旦Spring2.0对这些功能提供了完善的支持,那么将传统的Java企业应用完全迁移到Spring框 架上面的技术障碍就一扫而空了。
因此Spring是一个野心很大的框架,从现在状况来看,Spring可以说是Java开源框架之集大成者,从未来来看,Spring将提供 J2EE厂商所能够提供的所有必要的功能,最终Spring将有可能取J2EE规范而代之,成为Java企业开发的事实平台和事实标准。
总体来说,Spring2.0将向未来的宏大目标又迈进了一大步。不过对于我等普通Java Web项目的开发需求来说,2.0的新特性也没有特别需要的。