gpt4 book ai didi

spring - 使用 Spring Hibernate 应用程序配置 OpenSessionInView 过滤器

转载 作者:行者123 更新时间:2023-12-04 18:08:18 25 4
gpt4 key购买 nike

我正在开发一个 Spring Hibernate Web 应用程序

早些时候,我只使用 dispatcher-servlet.xml 加载 Spring 配置,而没有使用 ContextLoaderListener,但是当我实现 OpenSessionInView 模式时,我必须在 web.xml 中提供一个 ContextLoaderListener 并创建一个新的 applicationContext.xml 并移动 hibernate 配置从 dispatcher-servlet.xml 到 applicationContext.xml。

我对这个变化有些怀疑。

下面是运行良好的代码。网页.xml

<display-name>PetClinic</display-name>

<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
</param-value>
</context-param>

<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>


<servlet>
<servlet-name>dispatcher</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/dispatcher-servlet.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>

<servlet-mapping>
<servlet-name>dispatcher</servlet-name>
<url-pattern>/forms/*</url-pattern>
</servlet-mapping>

<filter>
<filter-name>hibernateFilter</filter-name>
<filter-class>org.springframework.orm.hibernate3.support.OpenSessionInViewFilter</filter-class>
<init-param>
<param-name>sessionFactoryBeanName</param-name>
<param-value>sessionFactory</param-value>
</init-param>
</filter>

<filter-mapping>
<filter-name>hibernateFilter</filter-name>
<url-pattern>/forms/*</url-pattern>
</filter-mapping>

<welcome-file-list>
<welcome-file>index.jsp</welcome-file>
</welcome-file-list>

调度器-servlet.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>

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>

一个。谁能告诉我创建新的 applicationContext.xml 并将 hibernate 代码移至其中的原因?为什么不直接让代码放在 dispatcher-servlet.xml 中呢?

B.要在 Spring 中使用过滤器,我们是否需要 ContextLoaderListener,没有它过滤器将无法工作?

最佳答案

这是因为 spring 应用程序通常有两个上下文:根上下文和每个 servlet 调度程序上下文。

这背后的想法是,一个应用程序可以有多个带有 bean(例如 Controller )的 servlet 上下文,并且每个 servlet 上下文都有一个隔离的父根上下文,其中所有应用程序通用的 bean 都可用。

来自根上下文的 bean(例如 session 工厂)可以注入(inject)到 servlet 上下文 bean(例如 Controller )中,但反之则不行。

OpenSessionInViewFilter 从公共(public)根应用程序上下文 (applicationContext.xml) 检索 session 工厂,因为它无法事先知道要查看哪个 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);
}

所以这回答了问题 A:OpenSessionInViewFilter 需要在根应用程序上下文中找到 session 工厂,这解释了为什么需要将 session 工厂从 servlet 上下文 (dispatcher-servlet.xml) ) 到根上下文 (applicationContext.xml)。

对于问题 B,并非应用程序的所有过滤器都有这个问题,这是特定于需要访问某些 spring bean 的过滤器,它们需要知道在哪个上下文中查看。

关于spring - 使用 Spring Hibernate 应用程序配置 OpenSessionInView 过滤器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20925755/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com