Spring
Spring是一个轻量级的DI和AOP容器框架。
轻量级
轻量级重量级某种程度上是以启动程序需要的资源来决定。比如,EJB启动的时候,需要消耗大量的资源,内存,CPU等,所以是重量级。而Spring则不,所以是轻量级框架。专业点说就是量级主要是看对容器的依赖性所决定的,依赖性越小,越轻量.
(本人认为轻量级判断标准,是其初始化时所需的资源多寡、运行或者开发过程中程序依赖框架程度、开发所需资源如jar包等)
Spring是非侵入式的
基于spring开发的应用一般不依赖于spring所自带的类。
DI:称作依赖注入(Dependency Injection)和控制反转同义
- 具体而言,当一个角色需要另外一个角色协助的时候,在传统的程序设计中,通常有调用者来创建被调用者的实例(如new)。
- 但是在spring中创建被调用者将不再有调用者完成(发射),因此叫控制反转。创建被调用对象有Spring来完成,在容器实例化对象的时候主动的将被调用者(或者说它的依赖对象)注入给调用对象,因此又叫依赖注入。
AOP
- Spring对面向切面编程提供了强有力的支持,通过它让我们将业务逻辑从应用服务(如事务管理)中分离出来,实现了高内聚开发,应用对象只关注业务逻辑,不再负责其它系统问题(如日志、事务等)。Spring支持用户自定义切面。
- 面向对象编程将程序分成各个层次的对象,面向切面的程序将运行过程分解成各个切面。AOP是从运行程序的角度去考虑程序的结构,提取业务处理过程的切面,OOP是静态的抽象,AOP是动态的抽象,是对应用执行过程的步骤进行抽象,从而获得步骤之间的逻辑划分。
容器
Spring作为一个容器,因为它包含并且管理应用对象的生命周期和配置。如对象的创建、销毁、回调等。
框架
Spring作为一个框架,提供了一些基础功能,(如事务管理,持久层集成等),使开发人员更专注于开发应用逻辑。
Spring优点
- 使用Spring的IOC容器,将对象之间的依赖关系交给spring,降低组件之间的耦合性,让我们更专注于应用逻辑;
- 可以提供众多服务,事务管理等;
- AOP的很好支持,方便面向切面编程;
- 对主流的持久化框架提供了很好的集成支持,如Hibernate、Struts2、JPA、ibatis、mybatis等;
- Spring DI机制降低了业务对象替换的复杂性;
- Spring属于低侵入,代码污染极低;
- Spring的高度可开放性,并不强制依赖于Spring,开发者可以自由选择Spring部分或全部;
Struts2
Struts2 是一个相当强大的Java Web开源框架,是一个基于POJO的Action的MVC Web框架。它基于当年的Webwork和XWork框架,继承其优点,同时做了相当的改进。Struts2现在在Java Web开发界的地位可以说是大红大紫,从开发人员的角度来分析,Struts2之所以能够如此的深入开发人员之心,与其优良的设计是分不开的。
- Struts2基于MVC架构,框架结构清晰,开发流程一目了然
开发过程中,从具体的功能需求文档和前台界面,然后分析需要从前台传递哪些参数,确定参数的变量名称,在Action中设置相应的变量,这些参数在前台如何显示,并将页面上的一些控件适当使用Struts2提供的服务器端控件来代替,编写Action对应的方法来完成业务逻辑,最后配置相关的设置。整个过程很清晰明了;- 使用OGNL进行参数传递
OGNL提供了在Struts2里访问各种作用域中的数据的简单方式,你可以方便的获取Request,Attribute,Application,Session,Parameters中的数据。大大简化了开发人员在获取这些数据时的代码量。- 强大的拦截器
Struts2 的拦截器是一个Action级别的AOP,Struts2中的许多特性都是通过拦截器来实现的,例如异常处理,文件上传,验证等。拦截器是可配置与重用的,可以将一些通用的功能如:登录验证,权限验证等置于拦截器中以完成一些Java Web项目中比较通用的功能。在我实现的的一Web项目中,就是使用Struts2的拦截器来完成了系统中的权限验证功能。- 易于测试
Struts2的Action都是简单的POJO,这样可以方便的对Struts2的Action编写测试用例,大大方便了Java Web项目的测试。- 易于扩展的插件机制
在Struts2添加扩展是一件愉快而轻松的事情,只需要将所需要的Jar包放到WEB-INF/lib文件夹中,在struts.xml中作一些简单的设置就可以实现扩展。- 模块化
Struts2已经把模块化作为了体系架构中的基本思想,可以通过三种方法来将应用程序模块化:
- 将配置信息拆分成多个文件
- 把自包含的应用模块创建为插件
- 创建新的框架特性,即将与特定应用无关的新功能组织成插件,以添加到多个应用中去
- 全局结果与声明式异常
为应用程序添加全局的Result,和在配置文件中对异常进行处理,这样当处理过程中出现指定异常时,可以跳转到特定页面,这一功能十分实用。
struts1.X 、struts2比较
- Struts2和Struts1.x的差别,最明显的就是Struts2是一个pull-MVC架构。从开发者角度看,就是说需要显示给用户的数据可以直接从Action中获取,而不像Struts1.x那样,必须把相应的Bean存到Page、Request或者Session中才能获取。
- Struts1.x 必须继承org.apache.struts.action.Action或者其子类,表单数据封装在FormBean中。
- Struts 2无须继承任何类型或实现任何接口,表单数据包含在Action中,通过Getter和Setter获取。
虽然,在理论上Struts2的Action无须实现任何接口或者是继承任何的类,但是,在实际编程过程中,为了更加方便的实现Action,大多数情况下都会继承com.opensymphony.xwork2.ActionSupport类,并且重载(Override)此类里的String execute()方法。如下所示:
package ActionDiffer;
import java.text.DateFormat;
import java.util.Date;
import com.opensymphony.xwork2.ActionSupport;
public class ActionForStruts2 extends ActionSupport {
private String message;
public String getMessage() {
return message;
}
@Override
public String execute() {
message = " This is hello from strtuts2. Now is: " + DateFormat.getInstance().format( new Date());
return SUCCESS;
}
}
全面比较
特性 | Struts1.x | Struts2 |
---|---|---|
Action类 | Struts1.x要求Action类要扩展自一个抽象基类。Struts1.x的一个共有的问题是面向抽象类编程而不是面向接口编程。 | Struts2的Action类实现了一个Action接口,连同其他接口一起来实现可选择和自定义的服务。Struts2提供一个名叫ActionSupport的基类来实现一般使用的接口。当然,Action接口不是必须的。任何使用execute方法的POJO对象可以被当作Struts 2的Action对象来使用。 |
线程模型 | Struts1.x Action类是单例类,因为只有一个实例来控制所有的请求。单例类策略造成了一定的限制,并且给开发带来了额外的烦恼。Action资源必须是线程安全或者同步的。 | Struts2 Action对象为每一个请求都实例化对象,所以没有线程安全的问题。(实践中,servlet容器给每一个请求产生许多丟弃的对象,并且不会导致性能和垃圾回收问题)。 |
Servlet 依赖 | Struts1.x的Action类依赖于servlet API,当Action被调用时,以HttpServletRequest 和HttpServletResponse 作为参数传给execute方法。 | Struts2的Action和容器无关。Servlet上下文被表现为简单的Maps,允许Action被独立的测试。Struts2的Action可以访问最初的请求(如果需要的话)。但是,尽可能避免或排除其他元素直接访问HttpServletRequest 或HttpServletResponse 。 |
易测性 | 测试Struts1.x的主要问题是execute方法暴露了Servlet API这使得测试要依赖于容器)。第三方的扩展,如Struts TestCase,提供了一套Struts1的模拟对象(来进行测试)。 | Struts2的Action可以通过初始化、设置属性、调用方法来测试。依赖注入的支持也是测试变得更简单。 |
捕获输入 | Struts1.x使用ActionForm对象来捕获输入。象Action一样,所有的ActionForm必须扩展基类。因为其他的JavaBean不能作为ActionForm使用,开发者经常创建多余的类来捕获输入。DynaBeans可以被用来作为替代ActionForm的类来创建。但是,开发者可能是在重新描述(创建)已经存在的JavaBean(仍然会导致有冗余的javabean)。 | Struts2直接使用Action属性作为输入属性,消除了对第二个输入对象的需求。输入属性可能是有自己(子)属性的rich对象类型。Action属性能够通过web页面上的taglibs访问。Struts2也支持ActionForm模式。rich对象类型,包括业务对象,能够用作输入/输出对象。这种ModelDriven 特性简化了taglib对POJO输入对象的引用。 |
表达式语言 | Struts1.x整合JSTL,所以它使用JSTL的表达式语言。表达式语言有基本的图形对象移动,但是对集合和索引属性的支持很弱。 | Struts2使用JSTL,但是也支持一个更强大和灵活的表达式语言:”Object Graph Notation Language” (OGNL)。 |
将值绑定到页面 | Struts1.x使用标准JSP机制来绑定对象到页面上下文。 | Struts2使用“ValueStack”技术,使taglib能够访问值而不需要把你的页面(view)和对象绑定起来。ValueStack策略允许通过一系列名称相同但类型不同的属性重用页面(view)。 |
类型转换 | Struts1.x的ActionForm属性经常都是String。Struts 1.x使用Commons-Beanutils来进行类型转换。转换每一个类,而不是为每一个实例配置。 | Struts2使用OGNL进行类型转换。提供基本和常用对象的转换器。 |
验证 | Struts1.x支持在ActionForm的validate方法中手动校验,或者通过Commons Validator的扩展来校验。同一个类可以有不同的校验内容,但不能校验子对象。 | Struts2支持通过validate方法和XWork校验框架来进行校验。XWork校验框架使用为属性类类型定义的校验和内容校验,来支持chain校验子属性 |
Action执行控制 | Struts1.x支持每一个模块有单独的Request Processors(生命周期),但是模块中的所有Action必须共享相同的生命周期。 | Struts2支持通过拦截器堆栈(Interceptor Stacks)为每一个Action创建不同的生命周期。堆栈能够根据需要和不同的Action一起使用。 |
Spring MVC、Struts2的比较
我们用struts2时采用的传统的配置文件的方式,并没有使用传说中的0配置。spring3 mvc可以认为已经100%零配置了
Spring MVC和Struts2的区别
- 机制:spring mvc的入口是servlet,而struts2是filter(这里要指出,filter和servlet是不同的。
- 性能:spring会稍微比struts快。
- spring mvc是基于方法的设计,而sturts是基于类,每次发一次请求都会实例一个action,每个action都会被注入属性,而spring基于方法,粒度更细,但要小心把握像在servlet控制数据一样。
- spring3 mvc是方法级别的拦截,拦截到方法后根据参数上的注解,把request数据注入进去,在spring3 mvc中,一个方法对应一个request上下文。而struts2框架是类级别的拦截,每次来了请求就创建一个Action,然后调用setter getter方法把request中的数据注入;struts2实际上是通过setter getter方法与request打交道的;struts2中,一个Action对象对应一个request上下文。
- 参数传递:struts是在接受参数的时候,可以用属性来接受参数,这就说明参数是让多个方法共享的。
- 设计思想上:struts更加符合oop的编程思想, spring就比较谨慎,在servlet上扩展。
- intercepter的实现机制:
- struts有以自己的interceptor机制,spring mvc用的是独立的AOP方式。这样导致struts的配置文件量还是比spring mvc大,虽然struts的配置能继承,从使用上来讲,spring mvc使用更加简洁,开发效率Spring MVC确实比struts2高。
- spring mvc是方法级别的拦截,一个方法对应一个request上下文,而方法同时又跟一个url对应,所以说从架构本身上spring3 mvc就容易实现restful url。struts2是类级别的拦截,一个类对应一个request上下文;实现restful url要费劲,因为struts2 action的一个方法可以对应一个url;而其类属性却被所有方法共享,这也就无法用注解或其他方式标识其所属方法了。spring3 mvc的方法之间基本上独立的,独享request response数据,请求数据通过参数获取,处理结果通过ModelMap交回给框架方法之间不共享变量,而struts2搞的就比较乱,虽然方法之间也是独立的,但其所有Action变量是共享的,这不会影响程序运行,却给我们编码,读程序时带来麻烦。
6.验证,spring mvc的验证也是一个亮点,支持JSR303
,处理ajax
的请求更是方便,只需一个注解@ResponseBody
,然后直接返回响应文本即可。送上一段代码:
@RequestMapping(value=“/whitelists”)
public String index(ModelMap map) {
Account account = accountManager.getByDigitId(SecurityContextHolder.get().getDigitId());
List groupList = groupManager.findAllGroup(account.getId());
map.put(“account”, account);
map.put(“groupList”, groupList);
return “/group/group-index”;
}
// @ResponseBody ajax响应,处理Ajax请求也很方便
@RequestMapping(value=“/whitelist/{whiteListId}/del”)
@ResponseBody
public String delete(@PathVariable Integer whiteListId) {
whiteListManager.deleteWhiteList(whiteListId);
return “success”;
}
原文章链接: