springmvc 异步线程绑定session

场景:
  对spring mvc的controller进行拦截,且在s(springmvc)s(spring)h(hibernate)环境中异步处理数据。
问题:
1 spring aop配置:
   如果是对service/dao进行拦截处理,在applicationContext.xml中配置切点/处理切面等数据(项目中此文件名称会变化);
 如果是对controller进行拦截出,在servlet.xml中配置切点/处理切面等数据(项目中此文件名称会变化);
具体不同主要是因为controller和service/dao的初始化时间不一致,如果配置错误,将不能对对应的类进行正确的aop增强,导致aop无效(可以参考代理的原理)。
2 hibernate的session问题:
   在ssh环境中,为了保证session的一致性,spring通过filter在请求创建时对线程进行了绑定,保证controller/service/dao使用的是同一个session;但是如果我们使用线程池创建线程对数据进行处理,不存在绑定问题,在查询实体关联属性的时候会出现session提前关闭。具体异常如could not initialize proxy - no Session(即使你使用官方ThreadLocal绑定session,但是在dao拿到的session和此时绑定的必然不一样),解决方法,如下:
  // 创建session给TransactionSynchronizationManager
    /**reference OpenSessionInViewFilter.doFilterInternal*/
    public void sessionToSpring() {
        // single session mode
        if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
            // Do not modify the Session:
        } else {
            Session session = getSession(sessionFactory);
            TransactionSynchronizationManager.bindResource(sessionFactory,
                    new SessionHolder(session));
        }
    }
    // 创建session
    /**copy OpenSessionInViewFilter.getSession*/
    public Session getSession(SessionFactory sessionFactory) {
        Session session = SessionFactoryUtils.getSession(sessionFactory, true);
        FlushMode flushMode = FlushMode.MANUAL;
        if (flushMode != null) {
            session.setFlushMode(flushMode);
        }
        return session;
    }
    // 关闭
    /**reference OpenSessionInViewFilter.doFilterInternal*/
    public void sessionClose() {
        SessionHolder sessionHolder =
                (SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
        SessionFactoryUtils.closeSession(sessionHolder.getSession());
    }





你可能感兴趣的:(springmvc 异步线程绑定session)