---恢复内容开始---

 /*
* 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的更多相关文章

  1. ssh中org.springframework.orm.hibernate4.support.OpenSessionInViewFilter的作用及配置

     org.springframework.orm.hibernate4.support.OpenSessionInViewFilter 是Spring为我们解决Hibernate的Session的关闭 ...

  2. org.springframework.orm.hibernate4.support.OpenSessionInterceptor

    /* * Copyright 2002-2014 the original author or authors. * * Licensed under the Apache License, Vers ...

  3. org.springframework.orm.hibernate3.support.OpenSessionInViewFilter作用

    在Spring与Hibernate集成时在web.xml要加入这样的过滤器: <filter> <filter-name>openSessionInView</filte ...

  4. Caused by: java.lang.ClassNotFoundException: org.springframework.orm.hibernate4.HibernateTemplate

    1.错误描述 严重: Context initialization failed org.springframework.beans.factory.CannotLoadBeanClassExcept ...

  5. hibernate4 , spring3 使用 org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean 报错 Implementing class

    错误代码如下 Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with ...

  6. org.springframework.orm.hibernate3.HibernateSystemException:

    org.springframework.orm.hibernate3.HibernateSystemException: The database returned no natively gener ...

  7. java.lang.ClassNotFoundException: org.springframework.orm.hibernate3.LocalSessionFactoryBean

    Caused by: java.lang.ClassNotFoundException: org.springframework.orm.hibernate3.LocalSessionFactoryB ...

  8. Initializing connection provider: org.springframework.orm.hibernate3.LocalDataSourceConnectionProvider停住了

    2015.1.24进行了服务器的搬家,搬家后,更换了新的IP,导致新的IP访问以前IP的数据库服务无法成功Initializing connection provider: org.springfra ...

  9. org.springframework.orm.hibernate3.LocalSessionFactoryBean的疑惑解决办法

    在项目中使用了SSH框架(Struts2 + Spring3+ Hibernate3),applicationContext中配置了sessionFactory <bean id="s ...

随机推荐

  1. 高负载linux调优

    调整Linux内核参数: # vi /etc/sysctl.conf# tells the Kernel it's ok if services bind to non-existant IP ADD ...

  2. HDU2255 奔小康赚大钱 —— 二分图最大权匹配 KM算法

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2255 奔小康赚大钱 Time Limit: 1000/1000 MS (Java/Others)    ...

  3. UVALive3126 Taxi Cab Scheme —— 最小路径覆盖

    题目链接:https://vjudge.net/problem/UVALive-3126 题解: 最小路径覆盖:即在图中找出尽量少的路径,使得每个结点恰好只存在于一条路径上.其中单独一个点也可以是一条 ...

  4. HDU1069 Monkey and Banana —— DP

    题目链接:http://acm.split.hdu.edu.cn/showproblem.php?pid=1069 Monkey and Banana Time Limit: 2000/1000 MS ...

  5. gfnormal 域名 是阿里云的高防IP

    最近DGA检出了一堆阿里高防的域名,例如:u3mbyv2siyaw2tnm.gfnormal09aq.com,然后专门查找了下相关文档. 例如 8264.com 这个网站启用了aliyun的高防DDo ...

  6. mac多线程下载神器

    本文参考:https://blog.csdn.net/orangleliu/article/details/46834429 神器:axel 安装(已经安装homebrew前提下,没有请参考:http ...

  7. I.MX6 bq27441 GPOUT interrupt

    /******************************************************************** * I.MX6 bq27441 GPOUT interrup ...

  8. 【ZJOI 2006】 物流运输

    [题目链接] 点击打开链接 [算法] 令cost(i,j) = 第i天到第j天走相同的路线,路线长度的最小值 那么,只需筛选出第i天到第j天可以装卸货物的码头,然后将这些码头之间连边,跑弗洛伊德(或其 ...

  9. FLASH OTP

    OTP 软件加密运用参考 为了防止软件被他人盗用,spansion flash给每个芯片植入了代表身份的unique ID,增加了OTP扇区,目前我们可以运用这两个特性,来实现软件的加密保护.软件加密 ...

  10. java.lang.NoSuchMethodError: org.springframework.web.context.ConfigurableWebApplicationContext.setId

    运行spring报了这个错误,网上说是spring版本冲突,检查maven依赖,发现我依赖的是spring-core.3.0.5,但是spring-orm和spring-tx依赖了spring-bea ...