為domain object注入service對象.

原理:利用Hibernate3提供的PostLoadEventListener在loadHibernate實體類的時候觸發PostLoadEvent事件,編寫一個自定義的事件監聽器,注入依賴的Spring Bean對象.此方法來自于ThoughtWorksPerrynFowler

import?org.hibernate.event.PostLoadEvent;
import?org.hibernate.event.PostLoadEventListener;
import?org.springframework.beans.factory.BeanFactory;
import?org.springframework.beans.factory.BeanFactoryAware;
import?org.springframework.beans.factory.config.AutowireCapableBeanFactory;

public?class?SpringHibernateInjector?implements?PostLoadEventListener,?BeanFactoryAware{

????AutowireCapableBeanFactory?beanFactory;
???
????
public?void?onPostLoad(PostLoadEvent?event)?{
????????Object?hibernateObject?
=?event.getEntity();
????????beanFactory.autowireBeanProperties(hibernateObject,?AutowireCapableBeanFactory.AUTOWIRE_BY_NAME,?
false);???
????}


????
public?void?setBeanFactory(BeanFactory?factory)??{
????????beanFactory?
=?(AutowireCapableBeanFactory)?factory;
????}


}
<bean?id="sessionFactory"
????????class
="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
????????
<property?name="dataSource">
????????????
<ref?bean="dataSource"?/>
????????
</property>
????????
<property?name="mappingResources">
????????????
<list>
????????????????domains.hbm.xml?here
????????????
</list>
????????
</property>
????????
<property?name="hibernateProperties">
????????????
<props>
????????????????
<prop?key="hibernate.dialect">
????????????????????org.hibernate.dialect.Oracle9Dialect
????????????????
</prop>
????????????????
<prop?key="hibernate.query.substitutions">
????????????????????true?1,?false?0
????????????????
</prop>
????????????????
<prop?key="hibernate.show_sql">false</prop>
????????????
</props>
????????
</property>
???????
<property?name="eventListeners">
??????????
<map>
????????????
<entry?key="post-load">
??????????????
<!--?This?hibernate?interceptor?allows?us?to?use?Spring?to?inject?services
?into?Hibernate?managed?domain?objects?
-->???
??????????????
<bean?class="yourpackage.SpringHibernateInjector"/>
????????????
</entry>????????
???????????
</map>
????
</property>
????
</bean>

domain object

?

package?hibernate;

import?java.util.List;

public?class?User?{

????
private?UserManager?userManager;

????
public?List?getArticles()?{
????????
return?userManager.getArticleByUser(this);
????}


????
public?void?save()?{
????????userManager.save(
this);
????}


????
public?void?delete()?{
????????userManager.delete(
this);
????}


????
public?UserManager?getUserManager()?{
????????
return?userManager;
????}


????
public?void?setUserManager(UserManager?userManager)?{
????????
this.userManager?=?userManager;
????}


}

package?hibernate;

public?class?Article?{
????
private?User?user;

????
public?User?getUser()?{
????????
return?user;
????}


????
public?void?setUser(User?user)?{
????????
this.user?=?user;
????}

????
}


service object
package?hibernate;

import?java.util.List;

public?interface?UserManager?{
????
public?void?save(User?user);
????
public?void?delete(User?user);
????
public?List?getArticleByUser(User?user);
}

在web層可以這樣用
user.save();
user.delete();

最有用的地方是下面所描述的
user.getArticles(),實際調用的是userManager.getArticleByUser(User user);
只需要在Article端配置many-to-one到User,而不需要User端的one-to-many到Article,利用這個單向的關聯來查詢得到列表
1.是可以實現延遲加載的效果,并且不用open session in view
2.可以分頁,分頁這個方式也比較特別,由javaeye的Prentice網友提出來的(一種傳遞分頁參數的方法),使用ServletFilter或Interceptor在WEB層截獲分頁的參數,
封裝成一個對象,然后保存在threadlocal中,Service進行查詢的時候可以按需從threadlocal中獲得分頁參數。