場景:
對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