在 JSF 托管 bean 中注入 Spring 托管 SessionFactory bean

Inject Spring managed SessionFactory bean in a JSF managed bean

如果我按如下方式配置了Spring+Hibernate,

<!-- Hibernate session factory -->
<bean id="sessionFactory"
  class="org.springframework.orm.hibernate4.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
    <props>
        <prop key="hibernate.dialect">org.hibernate.dialect.PostgreSQL82Dialect</prop>
        <prop key="hibernate.show_sql">true</prop>
        <prop key="hibernate.format_sql">true</prop>
        <prop key="hibernate.current_session_context_class">thread</prop>
    </props>
</property>
</bean>

<tx:annotation-driven transaction-manager="transactionManager"/>

<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
  <property name="sessionFactory" ref="sessionFactory" />
</bean>

<bean id="persistenceExceptionTranslationPostProcessor"
 class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>

如何将 Spring 会话工厂 bean 注入我的 JSF 托管 bean?

只要您使用 ContextLoaderListener 初始化了 Spring 上下文,您就可以从 JSF 上下文访问它。根据文档:

All Java web frameworks are built on top of the Servlet API, and so one can use the following code snippet to get access to this 'business context' ApplicationContext created by the ContextLoaderListener.

WebApplicationContext ctx = WebApplicationContextUtils.
    getWebApplicationContext(servletContext);

Spring 还有一个从 JSF 上下文中获取 bean 的隐式方法:

ApplicationContext ctx = FacesContextUtils
    .getWebApplicationContext(FacesContext.getCurrentInstance());
//Retrieve the bean by class or id
ctx.getBean("sessionFactory");

请记住,这种 bean 查找是违反 DI 规则的。不要在你拥有的每一个 bean 中执行它,它会降低它们的可测试性。相反,使用 @ApplicationScoped 托管 bean(您可以轻松模拟单元测试)以便 return Spring 上下文。

另请参阅: