Spring3.x_Struts2.x_Hibernate3.x整合之OpenSessionInView的实现

来源:互联网 发布:2016淘宝爆款打造方法 编辑:程序博客网 时间:2024/05/03 15:28

由于Hibernate存在延迟加载的问题,当Dao的事物提交之后,session就关闭此时如果到显示层就没有办法获取对象,使用OpenSessionInViewer是解决延迟加载问题的方案。
解决的思路:
1.在表示层开启session
    需要早表示层获取Spring的工厂,以此获取hibernate的SessionFactory
2.在Dao层获取表示层的session
    如果希望在Dao层获取表示层的数据,一个将要获取的数据存储到ThreadLocal
3.当整个过程执行完闭之后再关闭session
需要通过filter来解决问题
1.创建一个filter
//以下方法用来获取Spring的工厂和hibernate的SessionFactory

@Overridepublic void init(FilterConfig config) throws ServletException {    /**     * 使用WebApplicationContextUtils.getWebApplicationContext()来获取Spring的工厂     * 这种手段非常重要,一定要熟悉     */    wac = WebApplicationContextUtils.getWebApplicationContext(config            .getServletContext());    factory = (SessionFactory) wac.getBean("sessionFactory");}


2.通过ThreadLocal来处理session
private static ThreadLocal<Session> sessionHolder=new ThreadLocal<Session>();    private static void setSession(Session session){    sessionHolder.set(session);}public static Session getSession(){    return sessionHolder.get();}private static void removeSession(){    sessionHolder.remove();}


在web.xml中配置filter
<!-- 如果把这个filter放在struts2的filter之后,所有的请求都会被struts2给控制,所以这个filter就不起作用了, 必须将这个filter放在struts2的filter之前--><filter><filter-name>OpenSessionInViewFilter</filter-name><filter-class>org.oms.spring.filter.OpenSessionFilter</filter-class></filter><filter-mapping><filter-name>OpenSessionInViewFilter</filter-name><url-pattern>/*</url-pattern></filter-mapping>

OpenSessionFilter过滤器具体代码:

package org.oms.spring.filter;import java.io.IOException;import javax.servlet.Filter;import javax.servlet.FilterChain;import javax.servlet.FilterConfig;import javax.servlet.ServletException;import javax.servlet.ServletRequest;import javax.servlet.ServletResponse;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.springframework.web.context.WebApplicationContext;import org.springframework.web.context.support.WebApplicationContextUtils;public class OpenSessionFilter implements Filter {// Spring的工厂,在init中获取private static WebApplicationContext wac;private static SessionFactory factory;private static ThreadLocal<Session> sessionHolder=new ThreadLocal<Session>();private static void setSession(Session session){sessionHolder.set(session);}public static Session getSession(){return sessionHolder.get();}private static void removeSession(){sessionHolder.remove();}@Overridepublic void destroy() {}@Overridepublic void doFilter(ServletRequest request, ServletResponse response,FilterChain chain) throws IOException, ServletException {System.out.println("begin");// 开启session/** * 需要获取Spring工厂 如果使用new * ClassPathXmlApplicationContext()这种方式来获取Spring的工厂, * 和Spring在web.xml中得不兼容。 必须通过其他方法来获取 在Spring中可以通过Web */try {//设置sessionsetSession(factory.openSession());chain.doFilter(request, response);}finally{System.out.println("back");// 关闭sessionremoveSession();}}@Overridepublic void init(FilterConfig config) throws ServletException {/** * 使用WebApplicationContextUtils.getWebApplicationContext()来获取Spring的工厂 * 这种手段非常重要,一定要熟悉 */wac = WebApplicationContextUtils.getWebApplicationContext(config.getServletContext());factory = (SessionFactory) wac.getBean("sessionFactory");}}

BaseDao中得load方法修改:
@Overridepublic T load(int id) {//如果使用了自定义的OpenSessionFilter,需要按照如下方法来获取//return (T)OpenSessionFilter.getSession().load(getClz(), id);/** * 如果使用了Spring提供的OpenSessionInViewFilter就按照整合的方法处理即可 */        return  this.getHibernateTemplate().load(getClz(), id);}


这样就有效的解决了我们的延迟加载的问题!


当然在Spring中提供了OpenSessionInViewFilter的过滤器,以此我们只需要在web.xml中配置OpenSessionInViewFilter的过滤器,在load方法中继续使用HibernateTemplate的load方法!


个人备忘笔记~~~呵呵~~!





0 0
原创粉丝点击