为domain object注入service对象.
原理:利用Hibernate3提供的PostLoadEventListener在loadHibernate实体类的时候触发PostLoadEvent事件,编写一个自定义的事件监听器,注入依赖的Spring Bean对象.此方法来自于ThoughtWorks的 PerrynFowler
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中获得分页参数。