org.springframework.orm.hibernate4.support.OpenSessionInViewFilter
---恢复内容开始---
/*
* Copyright 2002-2014 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/ package org.springframework.orm.hibernate4.support; import java.io.IOException;
import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse; import org.hibernate.FlushMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.SessionFactory; import org.springframework.dao.DataAccessResourceFailureException;
import org.springframework.orm.hibernate4.SessionFactoryUtils;
import org.springframework.orm.hibernate4.SessionHolder;
import org.springframework.transaction.support.TransactionSynchronizationManager;
import org.springframework.web.context.WebApplicationContext;
import org.springframework.web.context.request.async.WebAsyncManager;
import org.springframework.web.context.request.async.WebAsyncUtils;
import org.springframework.web.context.support.WebApplicationContextUtils;
import org.springframework.web.filter.OncePerRequestFilter; /**
* Servlet 2.3 Filter that binds a Hibernate Session to the thread for the entire
* processing of the request. Intended for the "Open Session in View" pattern,
* i.e. to allow for lazy loading in web views despite the original transactions
* already being completed.
*使用过滤器将请求的全部 hibernate session 绑定到线程。 用于“打开回话视图” 模式,
允许在web 视图中延迟加载,尽管基本的事务已经完成,(虽然事务已经提交完成,但任然允许延迟加载数据?)
* <p>This filter makes Hibernate Sessions available via the current thread, which
* will be autodetected by transaction managers. It is suitable for service layer
* transactions via {@link org.springframework.orm.hibernate4.HibernateTransactionManager}
* as well as for non-transactional execution (if configured appropriately).
*这个过滤器使hibernaete session 可以通过当前线程,其将自动检测事务管理,适合于服务处通过HibernateTransactionManager 管理事务,以及非事务执行(如果适当配置)
* <p><b>NOTE</b>: This filter will by default <i>not</i> flush the Hibernate Session,
* with the flush mode set to {@code FlushMode.NEVER}. It assumes to be used
* in combination with service layer transactions that care for the flushing: The
* active transaction manager will temporarily change the flush mode to
* {@code FlushMode.AUTO} during a read-write transaction, with the flush
* mode reset to {@code FlushMode.NEVER} at the end of each transaction.
*
* <p><b>WARNING:</b> Applying this filter to existing logic can cause issues that
* have not appeared before, through the use of a single Hibernate Session for the
* processing of an entire request. In particular, the reassociation of persistent
* objects with a Hibernate Session has to occur at the very beginning of request
* processing, to avoid clashes with already loaded instances of the same objects.
*
* <p>Looks up the SessionFactory in Spring's root web application context.
* Supports a "sessionFactoryBeanName" filter init-param in {@code web.xml};
* the default bean name is "sessionFactory".
*
* @author Juergen Hoeller
* @since 3.1
* @see #lookupSessionFactory
* @see OpenSessionInViewInterceptor
* @see OpenSessionInterceptor
* @see org.springframework.orm.hibernate4.HibernateTransactionManager
* @see org.springframework.transaction.support.TransactionSynchronizationManager
* @see org.hibernate.SessionFactory#getCurrentSession()
*/
public class OpenSessionInViewFilter extends OncePerRequestFilter { public static final String DEFAULT_SESSION_FACTORY_BEAN_NAME = "sessionFactory"; private String sessionFactoryBeanName = DEFAULT_SESSION_FACTORY_BEAN_NAME; /**
* Set the bean name of the SessionFactory to fetch from Spring's
* root application context. Default is "sessionFactory".
* @see #DEFAULT_SESSION_FACTORY_BEAN_NAME
*/
public void setSessionFactoryBeanName(String sessionFactoryBeanName) {
this.sessionFactoryBeanName = sessionFactoryBeanName;
} /**
* Return the bean name of the SessionFactory to fetch from Spring's
* root application context.
*/
protected String getSessionFactoryBeanName() {
return this.sessionFactoryBeanName;
} /**
* Returns "false" so that the filter may re-bind the opened Hibernate
* {@code Session} to each asynchronously dispatched thread and postpone
* closing it until the very last asynchronous dispatch.
返回false 是因为这个filter 可以开启session的异步只读操作模式,延迟关闭它直到异步加载完成。
*/
@Override
protected boolean shouldNotFilterAsyncDispatch() {
return false;
} /**
* Returns "false" so that the filter may provide a Hibernate
* {@code Session} to each error dispatches.
返回false以便这个filter可以提供一个session的错误输出。
*/
@Override
protected boolean shouldNotFilterErrorDispatch() {
return false;
} @Override
protected void doFilterInternal(
HttpServletRequest request, HttpServletResponse response, FilterChain filterChain)
throws ServletException, IOException {
//通过指定的名称获取sessionFactory
SessionFactory sessionFactory = lookupSessionFactory(request);
boolean participate = false;
//通过当前的request请求获得web 异步管理器,如果没有异步管理器则创建一个并与request关联。
WebAsyncManager asyncManager = WebAsyncUtils.getAsyncManager(request);
//返回一个请求的属性名称已用于识别其已经过滤。
String key = getAlreadyFilteredAttributeName();
//检测这个sessionFactory是否绑定到当前线程。
if (TransactionSynchronizationManager.hasResource(sessionFactory)) {
// Do not modify the Session: just set the participate flag.
participate = true;
}
else {
//这个过滤器是否是异步执行的,因为一个filter是可以调用多个线程的单个请求的。
boolean isFirstRequest = !isAsyncDispatch(request);
if (isFirstRequest || !applySessionBindingInterceptor(asyncManager, key)) {
logger.debug("Opening Hibernate Session in OpenSessionInViewFilter");
Session session = openSession(sessionFactory);
//包装一个session以使下一句将其绑定到thread.
SessionHolder sessionHolder = new SessionHolder(session);
TransactionSynchronizationManager.bindResource(sessionFactory, sessionHolder);
//实例化一个opensessionInViewFilter类专用的异步请求拦截器,从其类解释来看很有必要。
AsyncRequestInterceptor interceptor = new AsyncRequestInterceptor(sessionFactory, sessionHolder);
//将异步请求拦截器与reques关联
asyncManager.registerCallableInterceptor(key, interceptor);
//延迟的请求
asyncManager.registerDeferredResultInterceptor(key, interceptor);
}
} try {
filterChain.doFilter(request, response);
} finally {
if (!participate) {
SessionHolder sessionHolder =
(SessionHolder) TransactionSynchronizationManager.unbindResource(sessionFactory);
if (!isAsyncStarted(request)) {
logger.debug("Closing Hibernate Session in OpenSessionInViewFilter");
SessionFactoryUtils.closeSession(sessionHolder.getSession());
}
}
}
} /**
* Look up the SessionFactory that this filter should use,
* taking the current HTTP request as argument.
* <p>The default implementation delegates to the {@link #lookupSessionFactory()}
* variant without arguments.
* @param request the current request
* @return the SessionFactory to use
*/
protected SessionFactory lookupSessionFactory(HttpServletRequest request) {
return lookupSessionFactory();
} /**
* Look up the SessionFactory that this filter should use.
* <p>The default implementation looks for a bean with the specified name
* in Spring's root application context.
* @return the SessionFactory to use
* @see #getSessionFactoryBeanName
*/
protected SessionFactory lookupSessionFactory() {
if (logger.isDebugEnabled()) {
logger.debug("Using SessionFactory '" + getSessionFactoryBeanName() + "' for OpenSessionInViewFilter");
}
WebApplicationContext wac = WebApplicationContextUtils.getRequiredWebApplicationContext(getServletContext());
return wac.getBean(getSessionFactoryBeanName(), SessionFactory.class);
} /**
* Open a Session for the SessionFactory that this filter uses.
* <p>The default implementation delegates to the {@link SessionFactory#openSession}
* method and sets the {@link Session}'s flush mode to "MANUAL".
打开session因为filter要使用,同时将session的事务提交模式设置为手动提交(MANUAL)
* @param sessionFactory the SessionFactory that this filter uses
* @return the Session to use
* @throws DataAccessResourceFailureException if the Session could not be created
* @see org.hibernate.FlushMode#MANUAL
*/
protected Session openSession(SessionFactory sessionFactory) throws DataAccessResourceFailureException {
try {
Session session = sessionFactory.openSession();
session.setFlushMode(FlushMode.MANUAL);
return session;
}
catch (HibernateException ex) {
throw new DataAccessResourceFailureException("Could not open Hibernate Session", ex);
}
}
/*检测前面获取的请求属性名是否已注册至异步管理器中,如果已经注册了,则通过绑定到当前线程的sessionFactory创建session*/
private boolean applySessionBindingInterceptor(WebAsyncManager asyncManager, String key) {
if (asyncManager.getCallableInterceptor(key) == null) {
return false;
}
((AsyncRequestInterceptor) asyncManager.getCallableInterceptor(key)).bindSession();
return true;
} }
---恢复内容结束---
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter的更多相关文章
- ssh中org.springframework.orm.hibernate4.support.OpenSessionInViewFilter的作用及配置
org.springframework.orm.hibernate4.support.OpenSessionInViewFilter 是Spring为我们解决Hibernate的Session的关闭 ...
- org.springframework.orm.hibernate4.support.OpenSessionInterceptor
/* * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Vers ...
- org.springframework.orm.hibernate3.support.OpenSessionInViewFilter作用
在Spring与Hibernate集成时在web.xml要加入这样的过滤器: <filter> <filter-name>openSessionInView</filte ...
- Caused by: java.lang.ClassNotFoundException: org.springframework.orm.hibernate4.HibernateTemplate
1.错误描述 严重: Context initialization failed org.springframework.beans.factory.CannotLoadBeanClassExcept ...
- hibernate4 , spring3 使用 org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean 报错 Implementing class
错误代码如下 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with ...
- org.springframework.orm.hibernate3.HibernateSystemException:
org.springframework.orm.hibernate3.HibernateSystemException: The database returned no natively gener ...
- java.lang.ClassNotFoundException: org.springframework.orm.hibernate3.LocalSessionFactoryBean
Caused by: java.lang.ClassNotFoundException: org.springframework.orm.hibernate3.LocalSessionFactoryB ...
- Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider停住了
2015.1.24进行了服务器的搬家,搬家后,更换了新的IP,导致新的IP访问以前IP的数据库服务无法成功Initializing connection provider: org.springfra ...
- org.springframework.orm.hibernate3.LocalSessionFactoryBean的疑惑解决办法
在项目中使用了SSH框架(Struts2 + Spring3+ Hibernate3),applicationContext中配置了sessionFactory <bean id="s ...
随机推荐
- RK3288以太网的mac地址调试笔记【学习笔记】【原创】
平台信息:内核:linux3.1.0系统:android/android6.0平台:RK3288 作者:庄泽彬(欢迎转载,请注明作者) 邮箱:2760715357@qq.com 说明:提供以太网mac ...
- android编译openssl静态库.a
github上有一个开源项目,已经为你编译openssl建好了工程. 地址:https://github.com/aluvalasuman/OpenSSL1.0.1cForAndroid 选择需要的版 ...
- AutoIT: ControlSetText
1. ControlSetText :可以摆脱Send的限制,在适当的文本框位置输入用户想要输入的信息.2. ControlGetText可以获取文本 Run("notepad.exe&qu ...
- request的Content-Type小结
一.Content-Type定义 Content-Type MediaType,即是Internet Media Type,互联网媒体类型:也叫做MIME类型,在Http协议消息头中,使用Conten ...
- Tool:XMind
ylbtech-Tool:XMind XMind 是一款非常实用的商业思维导图软件,应用全球最先进的Eclipse RCP 软件架构,全力打造易用.高效的可视化思维软件,强调软件的可扩展.跨平台.稳定 ...
- 3 Java对象的内存布局以及对象的访问定位
先来看看Java对象在内存中的布局 一 Java对象的内存布局 在HotSpot虚拟机中,对象在内存中的布局分为3个区域 对象头(Header) Mark Word(在32bit和64bit虚拟机 ...
- java jdbc 与mysql连接的基本步骤
Java与mysql链接的基本步骤: 第一步:注册驱动 方法一: DriverManager.registerDriver(new com.mysql.jdbc.Driver()); 方法二:设置属性 ...
- bzoj 2326: [HNOI2011]数学作业【dp+矩阵快速幂】
矩阵乘法一般不满足交换律!!所以快速幂里需要注意乘的顺序!! 其实不难,设f[i]为i的答案,那么f[i]=(f[i-1]w[i]+i)%mod,w[i]是1e(i的位数),这个很容易写成矩阵的形式, ...
- [App Store Connect帮助]七、在 App Store 上发行(2.4)设定价格与销售范围:安排价格调整
如果您拥有<付费应用程序协议>,则可以为您的 App 安排随时间推移的价格调整.您可以安排具有明确开始日期和结束日期的定价调整,以及没有结束日期的永久性定价调整.例如,您可以设置一个为期 ...
- Quartz.Net实现的定时执行任务调度
在之前的文章<推荐一个简单.轻量.功能非常强大的C#/ASP.NET定时任务执行管理器组件–FluentScheduler>和<简单.轻量.功能非常强大的C#/ASP.NET定时调度 ...