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());
    }spring

相關文章
相關標籤/搜索