毫无疑问,在实例化完Person实体或从数据库中取出Person实体后就应该可以使用NotificationService了,无需手工设置。
使用Spring实现自动装配
我们使用Spring的自动装配来实现这个功能,这是通过Java单例类RichDomainObjectFactory达成的:
|
通过将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,这样可以拦截和定制实体加载等事件。为了自动装配刚加载的实体,需要使用如下的拦截器实现:
|
该拦截器需要做的唯一一件事就是将加载的实体传递给RichDomainObjectFactory的autowire方法。对于该示例应用来说,onLoad方法的实现保证了每次从数据库中加载Person实体后都将NotificationService注入其中。
此外,还需要通过hibernate.ejb.interceptor属性将拦截器注册到JPA的持久性上下文中:
|