Spring2.0的的新特性

来源:互联网 发布:centos虚拟机连外网 编辑:程序博客网 时间:2024/05/16 05:49
  Spring框架发展实在迅速,1.x系列还火到不行的时候,2.x系列立马来了,大有一统J2EE轻量级开发标准之势。现在市面上介绍Spring2.0的书籍,已经铺天盖地地袭来,显然写这篇文章稍微有些晚,不过应某些网友的的要求,加上本文高度归纳前瞻的观点还是颇有价值的,以下便稍微谈一下Spring2.0的一些新特性好了。
  1.引入基于Xml-Schema的配置语法,简化了Xml的配置
  2.引入新的Bean作用域(request和session范围)
  3.可扩展的容器级Xml配置(Spring官方文档将这个功能上升到了DSL级别)
  4.AOP有了很大改进,更无缝地整合了AspectJ,为管理Spring容器外的对象提供了可能
  5.JdbcTemplate的改进(增加了NamedParameterJdbcTemplate和SimpleJdbcTemplate)
  6.更简单的事务配置
  7.Spring Web MVC的大幅改进和增强(引入了CoC的观点和增强了的标签库)
  8.Spring的Scheduling支持引入TaskExecutor抽象
  9.支持JPA,支持异步JMS,更好的JMX支持
  10.支持动态语言,JRuby,Groovy,BeanShell

  就以上10大特性,接着分别展开介绍:
  1.引入基于Xml-Schema的配置语法,简化了Xml的配置
  在Spring1.x中,bean的xml配置采用xml-dtd的方式,2.x引入了xml-schema的方式(当然也完全支持先前的方式),这一引入大大简化了bean的xml配置烦琐程度。Spring容器提供了许多公用特性的namespace(xml-schema的概念)定义方法,随便举几个例子:
  a.定义集合:
    Spring 1.x Style:
    <bean id="emailList" class="org.springframework.beans.factory.config.ListFactoryBean">
      <property name="sourceList">
        <list>
          <value>aa@hotmail.com</value>
          <value>bb@hotmail.com</value>
        </list>
      </property>
    </bean>
    Spring 2.x Style:
    <util:list id="emailList">
      <value>aa@hotmail.com</value>
      <value>bb@hotmail.com</value>
    </util:list>
  b.定义JNDI获取:
    Spring 1.x Style:
    <bean id="jndiBean" class="org.springframework.jndi.JndiObjectFactoryBean">
      <property name="jndiName" value="jdbc/MyDataSource"/>
    </bean>
    Spring 2.x Style:
    <jee:jndi-lookup id="jndiBean" jndi-name="jdbc/MyDataSource"/>
  2.引入新的Bean作用域(request和session范围)
  可以记得,在Spring1.x中,bean只有singleton和prototype两种作用域,并且是通过singleton开关来控制的。而2.x则引入了更多的作用域,并且其语法也发生了变化,在2.x中使用了scope元素来定义bean的作用域,从而废弃了singleton开关。当然如果你希望使用之前的定义方法也完全可以,只是你必需使用Spring1.x的DTD。如下:
  Spring 1.x Style:
    <bean id="logingAction" class="demo.LoginAction" singleton="true"/>
  Spring 2.x Style:
    <bean id="logingAction" class="demo.LoginAction" scope="request(session|singleton..)"/>
  关于这两个新引入的作用域背后,其实还有蛮多的学问,Spring官方文档就这个议题的DI(Dependency Injection)有一段比较详尽的描述,在此归纳一下:
  要向目标bean注射作用域为request或session的源bean,必须提供出源bean的代理(容器才足以智能地获取到
作用域为request或session的真实bean对象),像下面这样:
  <!--源bean-->
  <bean id="userRef" class="demo.User" scope="session">
    <!--提供出源bean的代理-->
    <aop:scoped-proxy/>
  </bean>
  <!--目标bean-->
  <bean id="userManager" class="demo.UserManager" scope="singleton">
    <!--向目标bean注射源bean的代理-->
    <property name="userRef" ref="userRef"/>
  </bean>
  如果不提供出代理,则每次会获取到首次容器初始化的bean实例,这是不正确的,详见Spring官方文档。
  3.可扩展的容器级Xml配置(Spring官方文档将这个功能上升到了DSL级别)
  根据我的理解,使用了容器级这个修饰词,那么什么是容器级xml配置,简单来说就是Spring2.0提供出了一种手段,可通过Xml等手段来扩展容器的功能。比如我可以书写一些Xml定义一些规则,然后插入容器中,当需要使用这些规则的时候,就可以简单地像通过使用容器默认提供的特性一样使用这些规则,以xml-schema的形式。比如:<hello:say content="I am Spirit.J"/>,显然<hello:say>是我自己定义的一套规则,而不是容器预定义的。这样看来,按照官方为Spring贴金的说法,真的是有点DSL(Domain Specific Language)的味道,有点寒了不过如果让我来贴金的话,我认为还是DSC比较妥当(Domain Specific Container),毕竟Spring还没有上升到语言到高度。详见Spring官方文档
  4.AOP有了很大改进,更无缝地整合了AspectJ,为管理Spring容器外的对象提供了可能
  AOP一向是Spring的一大特色和亮点,Spring2.x带来了全新的AOP feature,最大的改进是更加无缝地提供了对AspectJ的整合。<<精通Spring-Java轻量级架构开发实践>>一书中,我曾在第三章详细介绍了AOP的概念以及AspectJ的开发,并在第六章花了很多笔墨介绍Spring AOP。如果有些朋友不能很快入手Spring2.x的AOP,我建议可先阅读这本书。
  如果没有Spring2.x的AspectJ支持,显然就需要通过AspectJ
特定的编译器,以完成AOP功能的织入。比如在Eclipse中,如果没有AJDT插件,就不能编译使用AspectJ。而Spring2.x的到来,改变了这一状况,于是现在我们多了很多选择,可以使用AspectJ;可以通过@AspectJ(Spring2.x支持,需要JDK5以上的Annotation);可以使用Schema-base AOP(Spring2.x支持);也可以依然使用'朴素'的Spring AOP API和早先的AOP Xml配置;稍微提一下@AspectJ的一个额外功能,现在Spring2.x可以通过@AspectJ来管理Spring容器外的任何对象了,比如EJB,Servlet,POJO等等,这也是Spring官方推荐的管理容器外对象的方法。想了一下,这个功能实在是影响深远,更细致的介绍可以参考Spring官方文档。
  5.JdbcTemplate的改进(增加了NamedParameterJdbcTemplate等)
  还记得JdbcTemplate的易用吗?很快,Spring2.x又新增了几个JdbcTemplate以及相关的辅助类,NamedParameterJdbcTemplate允许通过Map的名值对形式来定义Sql语句的参数了,这就使得我们可不仅仅受限于传统JDBC以"?"带入Sql参数的方式了,NamedParameterJdbcTemplate不仅允许直接使用Java.util.Map,还提供了一个简单的Map包装类MapSqlParameterSource,为动态构造Sql条件提供了捷径。比如:
  public int getUserCount(final String user) {
    String sql = "select count(*) from user
                  where firstname = :first_name
                    and lastname = :last_name";

    NamedParameterJdbcTemplate tempate = new NamedParameterJdbcTemplate(this.getDataSource());
    SqlParameterSource params = new MapSqlParameterSource();
    params.addValue("first_name", user.getFirstName());
    params.addValue("last_name", user.getLastName());

    return tempate.quertForInt(sql, params);
  }
此外,
SqlParameterSource接口还提供了一个实现:BeanPropertySqlParameterSource,它可根据JavaBean的属性来填充Sql条件的占位符,怎么看,这些个玩意儿都有点Ibatis的味道。
  6.更简单的事务配置
  可声明的事务配置,Spring的又一个亮点。籍由Spring2.x对AOP语法的改进以及AspectJ的整合,在Spring中声明事务不仅得到了简化,同时也变得更为强大。下面PetStore的例子一目了然:
  Spring 1.x Style:
  <bean id="baseTransactionProxy" class="org.springframework.transaction.interceptor.TransactionProxyFactoryBean"
      abstract="true">
    <property name="transactionManager" ref="transactionManager"/>
    <property name="transactionAttributes">
      <props>
        <prop key="insert*">PROPAGATION_REQUIRED</prop>
        <prop key="update*">PROPAGATION_REQUIRED</prop>
        <prop key="*">PROPAGATION_REQUIRED,readOnly</prop>
      </props>
    </property>
  </bean>
  <bean id="petStore" parent="baseTransactionProxy">
    <property name="target">
      <bean class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
        ...
      </bean>
    </property>
  </bean>
  Spring 2.x Style:
  <bean id="petStore" class="org.springframework.samples.jpetstore.domain.logic.PetStoreImpl">
    ...
  </bean>
  <aop:config>
    <aop:advisor pointcut="execution(* *..PetStoreFacade.*(..))" advice-ref="txAdvice"/>
  </aop:config>
  <tx:advice id="txAdvice">
    <tx:attributes>
      <tx:method name="insert*"/>
      <tx:method name="update*"/>
      <tx:method name="*" read-only="true"/>
    </tx:attributes>
  </tx:advice>
  7.Spring Web MVC的大幅改进和增强(引入了CoC的观点和增强了的标签库)
  Spring2.x中,Web部分尤其是Spring MVC得到了长足的改进,不仅新增了很多JSP标签库(可参考spring-form.tld),而且对CoC(Convention Over Configuration)的观点提供了明确支持。所谓CoC,即通过一定的组件命名规约,可减少配置和编码的数量,从而带来开发效率的上升,不过这个偏编程美学的东西这里就不予介绍了,可详细参考Spring的官方文档。
  8.Spring的Scheduling支持引入TaskExecutor抽象
  还记得在Spring1.x中,通过使用Spring对Scheduling的支持觉得挺过瘾的,客户端编程和配置都非常方便。然而看了Spring2.x的发布包之后,发现1.x的支持实在少得可怜(有点像玩具包了,仅仅是JDK的Timer以及OpenSymphony的Quartz而已)。原来Spring2.x对Scheduling功能强化了很多,无论如何Scheduling背后总有Multi Thread的概念,有了Multi Thread,自然而然会有ThreadPool的实现。引入TaskExecutor抽象,根据Spring官方的说明,主要是为了摆脱对Java5的java.util.concurrent.Executor(即Java5的ThreadPool实现)的依赖。好了,现在由于Spring2.x背后的Scheduling Infrastructure足够抽象,为其注入不同的Muti Thread实现方式或者ThreadPool实现都成为了可能,而不需要绑定在某几种实现上,可以使用Spring自己提供的ThreadPool;可以使用第三方提供的开源解决方案比如Quartz的ThreadPool;也可以使用由商业Application Server提供的更成熟的Thread Pool,Spring2.x目前提供了BEA和IBM都支持的CommonJ WorkManager,因此引入TaskExecutor抽象是个出色的改进。
  9.支持JPA,支持异步JMS,更好的JMX支持
  Spring2.x开始支持JPA(Java Persistent API),又一个持久层解决方案。在Spring2.x之前,只支持JMS的发送消息和同步接收消息,2.x开始支持异步接收消息了。Spring2.x开始支持JMX的Notification模型,开始支持声明式的控制MBean向MBeanServer的注册(不明白JMX的朋友可以参考<<精通Spring-Java轻量级架构开发实践>>一书)。详细内容请参考Spring官方文档。
  10.支持动态语言,JRuby,Groovy,BeanShell
  Spring2.x开始支持动态语言了,这充分表明了Spring集大成,集最新流行技术的一贯态度和野心。首先稍微讲讲静态动态语言的概念,简单来说静态语言大致在编译期决定行为,参数变量需要事先声明类型,并且一经声明不可改变,Java,C#,C++都是静态语言;而动态语言则在程序运行期决定行为,参数变量一般无需事先声明类型,也可随意改变,甚至无需编译,因此脚本化、代码量少、开发效率高是动态语言的一些特征,现在火到不行的RoR,还有这里讲的三种语言都是动态语言的范畴。静动态语言优劣这里不介绍了。
  Spring2.x充分肯定了动态语言的优势,另外给出了一个功能我非常感兴趣,Spring2.0系列已经可以通过动态脚本来配置Spring MVC Controller和Validator了,这就意味着Spring的xml配置在将来可以更多地实施动态脚本控制。Spring官方对这个feature的命名是"dynamic-language-backed bean",详细内容可参考Spring官方文档。