高手组合 Scala整合Spring框架

发表于:2011-2-18 10:42

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:张龙 译    来源:51Testing软件测试网采编

  关于集合

  Scala 2.7.x提供了一个方便的Java集合到Scala集合的转换类,这是通过隐式转换实现的。上面的示例将一个Java list转换为Scala list,如下代码所示:

  导入Scala.collection.jcl.Conversions类的所有方法:

import Scala.collection.jcl.Conversions._

  这个类提供了隐式的转换方法将Java集合转换为对应的Scala集合“包装器”。对于java.util.List来说,Scala会创建一个Scala.collection.jcl.BufferWrapper。

  调用BufferWrapper的toList()方法返回Scala.List集合的一个实例。

  下面的代码阐述了这个转换过程:

  • def findAll() : List[T]  = {   
  •     getJpaTemplate().find("from " + entityClass.getName).toList.asInstanceOf[List[T]]  
  • }
  •   总是手工调用“toList”方法来转换集合有些麻烦。幸好,Scala 2.8(在本文撰写之际尚未发布最终版)将会解决这个瑕疵,它可以通过scala.collection.JavaConversions类将Java转换为Scala,整个过程完全透明。

      关于回调

      可以通过隐式转换将Spring回调轻松转换为Scala函数,如GenericJpaDaoSupport对象中所示:

  • implicit def jpaCallbackWrapper[T](func:(EntityManager) => T) = {  
  •     new JpaCallback {  
  • def doInJpa(session:EntityManager ) = func(session).asInstanceOf[Object]}  
  • }
  •   借助于这个转换,我们可以通过一个函数来调用JpaTemplate的execute方法而无需匿名内部类JPACallback了,这样就能直接与感兴趣的对象打交道了:

    jpaTemplate.execute((em:EntityManager) => em.createQuery(…)// etc. );

      这么做消除了另一处样板代码。

      关于getter和setter

      默认情况下,Scala编译器并不会生成符合JavaBean约定的getter和setter方法。然而,可以通过在实例变量上使用Scala注解来生成JavaBean风格的getter和setter方法。下面的示例取自上文的PersonDaoTestCase:

  • import reflect._  
  • @BeanProperty var personDao:PersonDao = _
  •   @BeanProperty注解告诉Scala编译器生成setPersonDao(…)和getPersonDao()方法,而这正是Spring进行依赖注入所需的。这个简单的想法能为每个实例变量省掉3~6行的setter与getter方法代码。

      第二步:按需进行依赖注入的富领域对象

      到目前为止,我们精简了DAO模式的实现,该实现只能持久化实体的状态。实体本身并没有什么,它只维护了一个状态而已。对于领域驱动设计(DDD)的拥趸来说,这种简单的实体并不足以应对复杂领域的挑战。一个实体若想成为富领域对象不仅要包含状态,还得能调用业务服务。为了达成这一目标,需要一种透明的机制将服务注入到领域对象中,不管对象在何处实例化都该如此。

      Scala与Spring的整合可以在运行期轻松将服务透明地注入到各种对象中。后面将会提到,这种机制的技术基础是DDD,可以用一种优雅的方式将实体提升为富领域对象。

      需求

      为了说清楚何谓按需的依赖注入,我们为这个示例应用加一个新需求:在调用Person实体的link方法时,它不仅会链接相应的Person,还会调用NotificationService以通知链接的双方。下面的代码阐述了这个新需求:

  • class Person   
  • {     @BeanProperty var notificationService:NotificationService = _    def link(relation:Person) =   
  • {       relations.add(relation)       notificationService.nofity(PersonLinkageNotification(this, relation))      
  • }     //other code omitted for readability   
  •   }
  • 《2023软件测试行业现状调查报告》独家发布~

    关注51Testing

    联系我们

    快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

    法律顾问:上海兰迪律师事务所 项棋律师
    版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
    投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

    沪ICP备05003035号

    沪公网安备 31010102002173号