使用Spring Hibernate应用程序配置OpenSessionInView筛选器
我正在开发一个SpringHibernateWeb应用程序 之前我只使用dispatcher-servlet.xml加载Spring配置,没有使用ContextLoaderListener,但是当我实现OpenSessionInView模式时,我必须在web.xml中提供ContextLoaderListener,并创建一个新的applicationContext.xml&将hibernate配置从dispatcher-servlet.xml移到applicationContext.xml 我对这一变化有些怀疑 下面是工作正常的代码。 web.xml 宠物诊所 上下文配置位置 /WEB-INF/applicationContext.xml org.springframework.web.context.ContextLoaderListener 调度员 org.springframework.web.servlet.DispatcherServlet 上下文配置位置 /WEB-INF/dispatcher-servlet.xml 1. 调度员 /形式/* 冬眠过滤器 org.springframework.orm.hibernate3.support.OpenSessionInViewFilter sessionFactoryBeanName 会话工厂 冬眠过滤器 /形式/* index.jsp dispatcher-servlet.xml使用Spring Hibernate应用程序配置OpenSessionInView筛选器,spring,hibernate,jakarta-ee,spring-mvc,open-session-in-view,Spring,Hibernate,Jakarta Ee,Spring Mvc,Open Session In View,我正在开发一个SpringHibernateWeb应用程序 之前我只使用dispatcher-servlet.xml加载Spring配置,没有使用ContextLoaderListener,但是当我实现OpenSessionInView模式时,我必须在web.xml中提供ContextLoaderListener,并创建一个新的applicationContext.xml&将hibernate配置从dispatcher-servlet.xml移到applicationContext.xml 我对
<context:component-scan base-package="com.petclinic"/>
<bean id="messageSource" class="org.springframework.context.support.ResourceBundleMessageSource"
p:basename="messages"/>
<bean id="viewResolver"
class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix">
<value>/WEB-INF/view/</value>
</property>
<property name="suffix">
<value>.jsp</value>
</property>
</bean>
/WEB-INF/view/
.jsp
applicationContext.xml
<context:annotation-config />
<!-- <context:property-placeholder> XML element automatically registers a new PropertyPlaceholderConfigurer
bean in the Spring Context. -->
<context:property-placeholder location="classpath:database.properties" />
<!-- enable the configuration of transactional behavior based on annotations -->
<tx:annotation-driven transaction-manager="hibernateTransactionManager"/>
<!-- Creating DataSource -->
<bean id="dataSource"
class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${database.driver}" />
<property name="url" value="${database.url}" />
<property name="username" value="${database.user}" />
<property name="password" value="${database.password}" />
</bean>
<!-- To persist the object to database, the instance of SessionFactory interface is created.
SessionFactory is a singleton instance which implements Factory design pattern.
SessionFactory loads hibernate.cfg.xml and with the help of TransactionFactory and ConnectionProvider
implements all the configuration settings on a database. -->
<!-- Configuring SessionFactory -->
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="annotatedClasses">
<list>
<value>com.petclinic.Owner</value>
</list>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.dialect">${hibernate.dialect}</prop>
<prop key="hibernate.show_sql">${hibernate.show_sql}</prop>
<prop key="hibernate.hbm2ddl.auto">${hibernate.hbm2ddl.auto}</prop>
</props>
</property>
</bean>
<!-- Configuring Hibernate Transaction Manager -->
<bean id="hibernateTransactionManager"
class="org.springframework.orm.hibernate3.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
com.petclinic.Owner
${hibernate.dial}
${hibernate.show_sql}
${hibernate.hbm2ddl.auto}
A.谁能告诉我创建新applicationContext.xml并将hibernate代码移到其中的原因吗?为什么不让代码放在dispatcher-servlet.xml中呢
B.要在Spring中使用过滤器,我们需要ContextLoaderListener吗?没有它,过滤器不会工作吗?这是因为Spring应用程序通常有两个上下文:根上下文和每个servlet调度程序上下文 这背后的思想是,一个应用程序可以有多个servlet上下文和bean,比如控制器,每个servlet上下文都有一个独立的父根上下文,其中所有应用程序的公共bean都可用 来自根上下文(如会话工厂)的bean可以注入servlet上下文bean(如控制器),但不能反过来注入 OpenSessionInViewFilter从公共根应用程序上下文(applicationContext.xml)检索会话工厂,因为它无法预先知道在哪个servlet上下文中查找 OpenSessionInViewFilter的代码调用lookupSessionFactory,后者最终调用以下代码:
/**
* Find the root WebApplicationContext for this web application, which is
* typically loaded via {@link org.springframework.web.context.ContextLoaderListener}.
* <p>Will rethrow an exception that happened on root context startup,
* to differentiate between a failed context startup and no context at all.
* @param sc ServletContext to find the web application context for
* @return the root WebApplicationContext for this web app, or {@code null} if none
* @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
*/
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}
/**
*查找此web应用程序的根WebApplicationContext,它是
*通常通过{@link org.springframework.web.context.ContextLoaderListener}加载。
*将重新显示根上下文启动时发生的异常,
*区分上下文启动失败和完全没有上下文。
*@param sc ServletContext查找的web应用程序上下文
*@返回此web应用程序的根WebApplicationContext,如果没有,则返回{@code null}
*@请参阅org.springframework.web.context.WebApplicationContext#ROOT_web_APPLICATION_context_属性
*/
公共静态WebApplicationContext getWebApplicationContext(ServletContext sc){
返回getWebApplicationContext(sc,WebApplicationContext.ROOT\u WEB\u应用程序\u上下文\u属性);
}
这就回答了问题A:OpenSessionInViewFilter需要在根应用程序上下文中找到会话工厂,这就解释了为什么需要将会话工厂从servlet上下文(dispatcher servlet.xml)移动到根上下文(applicationContext.xml)
对于问题B,并非应用程序的所有过滤器都有此问题,这是需要访问某些spring bean的特定过滤器,它们需要知道在哪个上下文中进行查看。我将答案放在下面,说明为什么这是必要的,如果仍然有问题,请告诉我,但您必须执行的操作对于OSIV正常工作。我正在开一个博客,我的第一篇文章是关于OSIV的优点和缺点,如果你感兴趣的话,请看一看!!谢谢你的回复,伙计
/**
* Find the root WebApplicationContext for this web application, which is
* typically loaded via {@link org.springframework.web.context.ContextLoaderListener}.
* <p>Will rethrow an exception that happened on root context startup,
* to differentiate between a failed context startup and no context at all.
* @param sc ServletContext to find the web application context for
* @return the root WebApplicationContext for this web app, or {@code null} if none
* @see org.springframework.web.context.WebApplicationContext#ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE
*/
public static WebApplicationContext getWebApplicationContext(ServletContext sc) {
return getWebApplicationContext(sc, WebApplicationContext.ROOT_WEB_APPLICATION_CONTEXT_ATTRIBUTE);
}