选择显示字体大小

爱上spring的5个理由

爱上spring的5个理由

作者:bruce a tate (spring: a developer’s notebook的作者之一)

翻译:kelvincheng


版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
英文原文地址:
http://www.onjava.com/pub/a/onjava/2005/05/11/spring.html
中文地址:
http://www.matrix.org.cn/resource/article/43/43666_spring.html
关键词: spring hibernate pojo dependency injection



约摸15年前的6月的一个酷热的早上,我爬入一艘旧玻璃钢制小艇。这小艇十分老,船身碎片刺入我的手指,它的桨几乎是传统whitewate桨的两倍长。我似乎在游泳而不是在划船,但是无所谓。15年后,我依然为此着迷。

约两年前,我试了试spring project,这个被hibernate站点显著提到的东西。感觉就像那旧艇,十分适合我。为企业应用核心部分的发展,spring深深地融入了我的编程当中,所以我将其作为我的第4本javaspring:a developer’s  notebook的主题。在这篇文章中我会告诉你原因。

1.spring提供更好的平衡
在河中,我学会更多地利用我的腰部和背部的肌肉来划船,因为我的手臂肌肉无法坚持整天划船。我变得更有效率,更平衡地利用自己的肌肉。通过spring,我可以在每行代码中做更多的事。通过spring你会发现更多其优势,其中最重要的是在对象持久化上。这是一个来自hibernate访问数据对象的函数。
public list getreservations( ) {
  return gethibernatetemplate( ).find("from reservation");
}

注意那些你没看到的东西。这里没有任何事务处理。spring允许你建立配置代码去处理它。你不一定要通过关闭session来管理资源。你不一定写你自己的配置。你不一定在这个层次上管理异常,因为这些异常是未经检查的。你可以自由地在最适当的位置去管理他们。没用springhibernate方法的代码会是这样的:
public list getbikesoldway( ) throws exception {
  list bikes = null;
  session s = null;
  try {
    s = mysessionfactory.opensession( );
    bikes = s.find("from bike");
  }catch (exception ex) {
    //handle exception gracefully
  }finally {
    s.close( );
  }
  return bikes;
}

spring给我更多优势,让我编程更快,更易维护程序。

2.spring支持pojo编程
ejb 2.x彻底失败之后,我们都在寻找更多方式避免在每个bean中加入笨重的模型去表达企业服务。当然。我们需要事务,安全,持久化,有时还需要远程调用。用ejb时,我不得不去学庞大的api以及通过新的工具和部署过程来工作。结果我变成容器(container)提供的服务的奴隶。而在用spring时,我可以选择我自己的服务和持久化框架。我在pojos上编程并通过配置文件添加企业服务。
在sping:a developer’s notebook这本书中,我建立了一个rentabike的程序。我用我的pojohibrentabike取代了session bean 或者entity bean,它充当了我的数据访问对象。我还在别处添加了服务。spring配置文件是一个xml文件,被称为上下文。它含有在容器中的所有bean以及这些bean的属性,还有这些bean需要的服务。让我们来看看下面的例子。

target:
<bean id=&quot;rentabiketarget&quot; class=&quot;com.springbook.hibrentabike&quot;>
  <property name=&quot;storename&quot;>
    <value>bruce's bikes</value>
  </property>
  <property name=&quot;sessionfactory&quot;>
    <ref local=&quot;sessionfactory&quot;/>
  </property>
  <property name=&quot;transactionmanager&quot;>
    <ref local=&quot;transactionmanager&quot;/>
  </property>
</bean>


interceptor:
<bean name=&quot;transactioninterceptor&quot; 
    class=&quot;org.springframework.transaction.interceptor.transactioninterceptor&quot;>
  <property name=&quot;transactionmanager&quot;>
    <ref local=&quot;transactionmanager&quot;/>
  </property>
  <property name=&quot;transactionattributesource&quot;>
    <value>
      com.springbook.rentabike.transferreservation=
      propagation_required,-reservationtransferexception
      com.springbook.rentabike.save*=propagation_required
      com.springbook.rentabike.*=propagation_required,readonly
    </value>
  </property>
</bean>


proxy:
<bean id=&quot;rentabike&quot; class=&quot;org.springframework.aop.framework.proxyfactorybean&quot;>
  <property name=&quot;proxyinterfaces&quot;>
    <value>com.springbook.rentabike</value>
  </property>
  <property name=&quot;interceptornames&quot;>
    <value>transactioninterceptor,rentabiketarget</value>
  </property>
</bean>


注意这3个不同的bean: the proxy , the target, and the interceptors. the proxy将调用pojo,以及pojo需要的任何服务。interceptors包含粘合各调用服务的代码,他们也说明了如何去对待the target中的每个方法。所有需要访问rantabike的人调用the proxy,这个开始事务访问the target(the pojo)的事务拦截器。thet target做自己的事返回给事务拦截器(提交事务的对象),返回到proxy和proxy的调用者。


figure 1. pojo programming in action

你在pojo外建立了你的程序,配置了它,spring会隐藏其他的东西。我是一个pojo编程者。

3.依赖注入有助易测性
spring通过叫依赖注入(dependency injection)的设计模式来提高你的易测性。当一个消费者(consumer)依赖一个从属物(我们会叫它一个服务),你会为consumer建立一个属性。spring将会建立这个consumer和服务,以及设置这个consumer的属性为服务的值。换种说法,spring在上下文中管理beans的生命周期,解决依赖性。这是个不通过spring的依赖注入的例子。首先是消费者(consumer),被作为程序的基本模样。
public class commandlineview {

  private rentabike rentabike;

  public commandlineview( ) {rentabike = new arraylistrentabike(&quot;bruce's bikes&quot;); }

public void setrentabike(rentabike rentabike){

  this.rentabike = rentabike;

}

  public void printallbikes( ) {
    system.out.println(rentabike.tostring( ));
    iterator iter = rentabike.getbikes().iterator( );
    while(iter.hasnext( )) {
      bike bike = (bike)iter.next( );
      system.out.println(bike.tostring( ));
    }
  }

  public static final void main(string&#91;&#93; args) {
    commandlineview clv = new commandlineview( );
    clv.printallbikes( );
  }


接着是service这个模型。这是个简单的通过数组表的实现,其依赖于在这个模型(rentabike)。
interface rentabike {
list getbikes( );
bike getbike(string serialno);
}

public class arraylistrentabike implements rentabike {
   private string storename;
   final list bikes = new arraylist();
   public arraylistrentabike(string storename) {
      this.storename = storename;
      bikes.add(new bike(&quot;shimano&quot;, &quot;roadmaster&quot;, 20, &quot;11111&quot;, 15, &quot;fair&quot;));
      bikes.add(new bike(&quot;cannondale&quot;, &quot;f2000 xtr&quot;, 18, &quot;22222&quot;,12,&quot;excellent&quot;));
      bikes.add(new bike(&quot;trek&quot;,&quot;6000&quot;, 19, &quot;33333&quot;, 12.4, &quot;fair&quot;));
   }

   public string tostring() { return &quot;rentabike: &quot; + storename; }
   public list getbikes() { return bikes; }
   public bike getbike(string serialno) {
      iterator iter = bikes.iterator();
      while(iter.hasnext()) {
         bike bike = (bike)iter.next();
         if(serialno.equals(bike.getserialno())) return bike;
      }
      return null;
   }
}


这是装配程序。粗体的代码就是依赖注入。装配程序演示了服务和消费者,通过设置rentabike的属性解决了依赖性。
public class rentabikeassembler {
  public static final void main(string&#91;&#93; args) {
    commandlineview clv = new commandlineview( );
    rentabike rentabike = new arraylistrentabike(&quot;bruce's bikes&quot;);
    clv.setrentabike(rentabike);
    clv.printallbikes( );
  }
}


当然,spring将最终符合装配的法则。如果你将服务隐藏到接口程序中,那样你将可以向容器注入接口程序(interface)的任何实现(implementation)。
依赖注入(dependency injection)让你编写一个生产依赖和一个测试依赖。例如这个例子建立一个stub 对象,它让测试这个程序更轻松。(要更多地了解stubs和mocks,请看&ldquo;mocks aren&rsquo;t stubs.&rdquo;).
你已经看到rentabike的hibernate实现,以及其数组表版本。我也许不想在完全hibernates实现的代码运行我的所有用户界面测试。而我更愿意简单地通过数组表实现接口。
依赖注入让我联合成品版(通过hibrentabike),开发版(通过arraylistrentabike列表)和测试版(通过mock对象)。当我用java编程的时候,我必须有依赖注入去取得这些mocks进入那些难以进入的位置。

4.控制转入简化jdbc
jdbc程序是丑陋的,冗长的和乏味的。一个好的抽象层可以改进它,spring让你通过查询语句和匿名的inner class来定制默认jdbc方法来去除那大部分苦力工作。这是一个简单的jdbc的例子。
jdbctemplate template = new jdbctemplate(datasource); 
final list names = new linkedlist();

template.query(&quot;select user.name from user&quot;,
  new rowcallbackhandler() {
      public void processrow(resultset rs) throws sqlexception {
        names.add(rs.getstring(1));
      }
  }
);


想想这个例子,查询如一个默认jdbc方法的方法。spring会为结果集中的每一行执行在匿名inner class里的processrow方法的。你在上下文中设置了数据源。而不需要担心开或者关的状态,或者连接,配置数据源,或者管理事务。你不需要说明一个外部的结果集,或者在更低的层次上管理异常,因为spring将你的sqlexception折叠放入一个共同的未检查的异常集。其他语言例如ruby和smalltalk经常通过代码块使用控制转入,但是在java中不经常使用。spring简化了艰巨的任务。

5.spring的社区兴旺
虽然一些开源项目不需要变得相当活跃而使其变得有用。例如juit做已定目标的工作。如果你喜欢编程模型的话,它有你需要的所有基本东西。而轻量级容器如spring需要一个充满活力的社区。spring是你可以找到的最活跃的社区之一,你可以拥有许多好处。

服务(service):通过spring你可以找到数百种不同的服务,从安全到系统管理,到工作流。在持久化上,你可以插入jdo,hibernate,top link,jdbc或者ojb.
支持和教育(support and education)::许多独立顾问提供spring服务,你可以在全世界得到出色的培训。

增强(enhancements):spring一年放出数个主要的发行版。在框架内的出色的测试和清晰的(factored 扩展)意味着每个发行版都是质量优良的。spring以及取得正在进行中的hbernate 3的支持,提供了一个全新的web流程框架。这所有都在最新的发行版中。
商业上支持(commercial support):像我这样的作者写spring的书。现在,你可以找到5本关于spring的书,以及许多含有部分spring内容的书。许多产品商也支持spring。许多开源框架例如geronimo和hibernate具有对spring的特殊支持。
spring社区让人们用这个框架变得更加容易。我可以雇用spring开发人员,培训他们。我可以阅读一些书籍来补充我的知识,取得一些帮助我做那些我需要做的所有事情。我没有找到为另一个容器的社区来得如此亲近。

资料:
如果你想读得更多,则有许多你可以取得地方:
martinfowler.com 有一些关于stubs and mocks 及 dependency injection.的文章。
这里有spring框架
我的第一本书,better, faster, lighter java, 总结了轻量(lightweight)开发方法。
本文源于spring: a developer's notebook 及其代码。 这是一本程序员注解的书,因此请注意勘误表,当然,可以使用范例代码简化工作。
还有这本o'reilly出版的书:hibernate: a developer's notebook.

作者简介:
bruce a. tate是划艇和山地自行车爱好者,是两个孩子的父亲。在他的业余时间,他在得克萨斯州的奥斯丁当独立顾问。他是4本书的作者,其中包括畅销的bitter java以及o&rsquo;reilly最近发行的better,faster,lighter java


 


关键字 本文所属关键字

相关 与本文相关文章

分类 所有文章关键字导航

源码编程相关

Java   Asp   PHP   .Net   XML   C/C++   CGI   VB   Jsp   J2ee   J2se   J2me   EJB   Servlet   Tomcat   Resin   Struts   Weblogic   Eclipse   ANT   GUI   JMS   Web servise   IDEA   Webphere   Hibernate   Spring   Jboss   Applet   Swing   Socket   Javamail   Perl   Ajax   P2P   安全   模式   框架   测试   开源   游戏

SQL数据库相关

My-SQL   Ms-SQL   Access   DB2   Oracle   Sybase   SQLserver   索引   存储过程   加密   数据库   分页   视图  

手机无线相关

3G   Wap   CDMA   GRPS   GSM   IVR   彩信   短信   无线   增值业务

网页设计制作相关

HTML   CSS   网页配色   网页特效   Javascript   VBscript   Dreamweaver   Frontpage   JS   Web   网站设计

网站建设推广相关

建站经验   网站优化   网站排名   推广   Alexa

操作系统/服务器相关

Windows XP   Windows 2000   Windows 2003   Windows Me   Windows 9.x   Linux   UNIX   注册表   操作系统   服务器   应用服务器

图形图像多媒体相关

Photoshop   Fireworks   Flash   Coreldraw   Illustrator   Freehand   Photoimpact   多媒体   图形图像

标准 网站致力的规范

Valid CSS!

无不良内容,无不良广告,无恶意代码

Valid XHTML 1.0 Transitional

creativecommons