关闭

高手组合 Scala整合Spring框架

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

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

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

  毫无疑问,在实例化完Person实体或从数据库中取出Person实体后就应该可以使用NotificationService了,无需手工设置。

  使用Spring实现自动装配

  我们使用Spring的自动装配来实现这个功能,这是通过Java单例类RichDomainObjectFactory达成的:

  •  public class RichDomainObjectFactory implements BeanFactoryAware   
  • {         
  • pritic RichDomainObjectFactory singleton = new   
  • RichDomainObjectFactory();              
  • public static RichDomainObjectFactory autoWireFactory()   
  • {           
  •  return singleton;        
  • }   
  • public void autowire(Object instance)   
  • {            
  • factory.autowireBeanProperties(instance)  
  • }         
  • public void setBeanFactory(BeanFactory factory) throws BeansException {            
  • this.factory = (AutowireCapableBeanFactory) factory;       
  •  }         
  •  }
  •   通过将RichDomainObjectFactory声明为Spring bean,Spring容器确保在容器初始化完毕后就设定好了AutowireCapableBeanFactory:

    <bean class="org.jsi.di.spring.RichDomainObjectFactory" factory-method="autoWireFactory"/>

      这里并没有让Spring容器创建自己的RichDomainObjectFactory实例,而是在bean定义中使用了factory-method属性,它会强制Spring使用autoWireFactory()方法返回的引用,该引用是单例的。这样会将AutowireCapableBeanFactory注入到单例的RichDomainObjectFactory中。由于可以在同一个类装载器范围内访问单例对象,这样该范围内的所有类都可以使用RichDomainObjectFactory了,它能以一种非侵入、松耦合的方式使用Spring的自动装配特性。毋庸置疑,Scala代码也可以访问到RichDomainObjectFactory单例并使用其自动装配功能。

      在设定完这个自动装配工厂后,接下来需要在代码/框架中定义钩子(hook)了。总的来说需要在两个地方定义:

      ◆ORM层,它负责从数据库中加载实体

      ◆需要“手工”创建新实体的代码中

      自动装配ORM层中的领域对象

      由于文中的示例代码使用了JPA/Hibernate,因此在实体加载后需要将这些框架所提供的设备挂载到RichDomainObjectFactory中。JPA/Hibernate提供了一个拦截器API,这样可以拦截和定制实体加载等事件。为了自动装配刚加载的实体,需要使用如下的拦截器实现:

  • class DependencyInjectionInterceptor extends EmptyInterceptor {  
  •     override def onLoad(instance:Object, id:Serializable, propertieValues:Array[Object],propertyNames:Array[String], propertyTypes:Array[Type]) = {  
  •       RichDomainObjectFactory.autoWireFactory.autowire(instance)  
  •       false  
  •    }  
  • }
  •   该拦截器需要做的唯一一件事就是将加载的实体传递给RichDomainObjectFactory的autowire方法。对于该示例应用来说,onLoad方法的实现保证了每次从数据库中加载Person实体后都将NotificationService注入其中。

      此外,还需要通过hibernate.ejb.interceptor属性将拦截器注册到JPA的持久性上下文中:

  • <persistence-unit name="ScalaSpringIntegration" transaction-type="RESOURCE_LOCAL"> 
  •      <provider>org.hibernate.ejb.HibernatePersistence</provider> 
  •      <property name="hibernate.ejb.interceptor"                             value="org.jsi.domain.jpa.DependencyInjectionInterceptor" />   
  •      </properties> 
  •      <!-- more properties here--> 
  • </persistence-unit>
  • 《2023软件测试行业现状调查报告》独家发布~

    关注51Testing

    联系我们

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

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

    沪ICP备05003035号

    沪公网安备 31010102002173号