高手组合 Scala整合Spring框架

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

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

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

分享:

  DependencyInjectionInterceptor非常强大,每次从数据库中加载实体后它都能将在Spring中配置的服务注入其中。那如果我们在应用代码而非JAP等框架中实例化实体时又该怎么办呢?

  自动装配“手工”实例化的领域对象

  要想自动装配应用代码中实例化的实体,最简单也是最笨的办法就是通过RichDomainObjectFactory的方式显式进行自动装配。由于这个办法将RichDomainObjectFactory类与实体创建代码紧耦合起来,因此并不推荐使用。幸好,Scala提供了“组件对象”的概念,它担负起工厂的职责,可以灵活实现构造逻辑。

  对于该示例应用,我们采用如下方式实现Person对象以便“自动”提供自动装配功能:

  • import org.jsi.di.spring.RichDomainObjectFactory._  
  • object Person {  
  •     def apply(name:String) = {  
  •        autoWireFactory.autowire(new Person(name))  
  •     }  
  • }
  •   import声明会导入RichDomainObjectFactory的所有静态方法,其中的autoWireFactory()方法会处理RichDomainObjectFactory单例对象。

      Scala对象另一个便利的构造手段就是apply()方法,其规则是拥有apply方法的任何对象在调用时可以省略掉.apply()。这样,Scala会将对Person()的调用转给Person.apply(),因此可以将自动装配代码放到apply()方法中。

      这样,无需使用“new”关键字就可以调用Person()了,它会返回一个新的实体,返回前所有必要的服务都已经注入进去了,该实体也成为一个“富”DDD实体了。

      现在我们可以使用富领域对象了,它是可持久化的,也能在需要时调用其中的服务:

  • trait JpaPersistable[T] extends JpaDaoSupport  {  
  •    def getEntity:T;  
  •  
  •    def findAll():List[T] = {   
  •         getJpaTemplate().find("from " + getEntityClass.getName).toList.asInstanceOf[List[T]]     
  •    }  
  •  
  •    def save():T = {  
  •        getJpaTemplate().persist(getEntity)  
  •        getEntity  
  •    }  
  •  
  •    def remove() = {  
  •        getJpaTemplate().remove(getEntity);          
  •    }  
  •         
  •    def findById(id:Serializable):T = {  
  •         getJpaTemplate().find(getEntityClass, id).asInstanceOf[T];  
  •    }  
  •    //…more code omitted for readability        
  • }
  •   在继续之前,我们需要解释一下为何要用Java而不是Scala来实现RichDomainObjectFactory,原因是由Scala处理static的方式造成的。Scala故意没有提供static关键字,因为static与复合的OO/函数式范式有冲突。Scala语言所提供的唯一一个静态特性就是对象,其在Java中的等价物就是单例。由于Scala缺少static方法,因此Spring没法通过上文介绍的factory-method属性获得RichDomainObjectFactory这样的工厂对象。这样,我们就没法将Spring的AutowireCapableBeanFactory直接注入到Person对象中了。因此,这里使用Java而非Scala来利用Spring的自动装配功能,它能彻底填充static鸿沟。

      第三步:使用Scala traits打造功能完善的领域对象

      到目前为止一切尚好,此外,Scala还为OO纯粹主义者提供了更多特性。使用DAO持久化实体与纯粹的OO理念有些许冲突。从广泛使用的DAO/Repository模式的角度来说,DAO只负责执行持久化操作,而实体则只维护其状态。但纯粹的OO对象不仅有状态,还要有行为。

      上文介绍的实体是拥有服务的,这些服务封装了一些行为性职责,但持久化部分并不在其中。为什么不把所有的行为性和状态性职责都赋给实体呢,就像OO纯粹主义者所倡导的那样,让实体自己负责持久化操作。事实上,这是习惯问题。但使用Java很难以优雅的方式让实体自己去实现持久化操作。这种设计严重依赖于继承,因为持久化方法要在父类中实现。这种方式相当麻烦,也缺少灵活性。Java从概念上就缺少一个良好设计的根基,没法很好地实现这种逻辑。但Scala则不同,因为Scala有traits。

    精选软件测试好文,快来阅读吧~

    关注51Testing

    联系我们

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

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

    沪ICP备05003035号

    沪公网安备 31010102002173号