【发布时间】:2025-12-16 07:30:01
【问题描述】:
我们想通过集成 Spring CDI + JSF + Spring Security 来创建 Web 应用程序。我们已经配置了上述所有框架,并且我们认为一切正常,但是在实现注销功能期间,我们意识到 JSF 的 ManagedBeans 没有在应该创建的时候创建。例如:我们在会话范围内创建了托管 bean,并且我们预计该 bean 将在注销和使会话无效后被删除。
不幸的是,重新登录后托管bean实例仍然存在(每个用户信息都与注销前相同:()。我们添加了更多日志,并且我们注意到我们的托管bean是在启动应用程序期间创建的,而不是在初始化用户会话,我们发现是spring应用上下文配置文件中context:component-scan base-package="..."引起的,所以我们添加了context:exclude-filter type="" expression=""但之后不再创建任何托管 bean :(。我们在下面添加了一些清单。
applicationContext.xml
<context:property-placeholder location="classpath:application.properties"/>
<context:component-scan base-package="com.teaman" />
<mongo:repositories base-package="com.teaman.dao" />
<mongo:mongo host="${mongodb.hostname}" port="${mongodb.port}" id="mongo" />
<mongo:db-factory id="mongoDbFactory" mongo-ref="mongo" dbname="${mongodb.dbname}" />
<mongo:mapping-converter id="converter" db-factory-ref="mongoDbFactory" />
<bean id="mongoTemplate" class="org.springframework.data.mongodb.core.MongoTemplate">
<constructor-arg name="mongoDbFactory" ref="mongoDbFactory" />
<constructor-arg name="mongoConverter" ref="converter"/>
<property name="writeConcern">
<util:constant static-field="com.mongodb.WriteConcern.SAFE" ></util:constant>
</property>
</bean>
<!-- Use this post processor to translate any MongoExceptions thrown in @Repository annotated classes -->
<bean class="org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor"/>
<bean id="gridTemplate" class="org.springframework.data.mongodb.gridfs.GridFsTemplate">
<constructor-arg ref="mongoDbFactory" />
<constructor-arg ref="converter" />
</bean>
<bean id="teaManAuthenticationSuccessHandler" class="com.teaman.authentication.handler.TeaManAuthenticationSuccessHandler"/>
beans.xml
<beans xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/beans_1_0.xsd">
</beans>
faces-config.xml
<application>
<el-resolver>
org.springframework.web.jsf.el.SpringBeanFacesELResolver
</el-resolver>
<locale-config>
<default-locale>pl</default-locale>
</locale-config>
<resource-bundle>
<base-name>com.teaman.locales.locale</base-name>
<var>msg</var>
</resource-bundle>
</application>
<application>
<message-bundle>com.teaman.ValidationMessages</message-bundle>
</application>
<lifecycle>
<phase-listener>com.teaman.bean.LoginErrorPhaseListener</phase-listener>
</lifecycle>
web.xml
<context-param>
<param-name>javax.faces.PROJECT_STAGE</param-name>
<param-value>Development</param-value>
</context-param>
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>
/WEB-INF/applicationContext.xml
/WEB-INF/securityContext.xml
</param-value>
</context-param>
<context-param>
<param-name>javax.faces.STATE_SAVING_METHOD</param-name>
<param-value>client</param-value>
</context-param>
<context-param>
<param-name>javax.faces.INTERPRET_EMPTY_STRING_SUBMITTED_VALUES_AS_NULL</param-name>
<param-value>true</param-value>
</context-param>
<!-- Context listener responsible for loading spring applicationContext file -->
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
<servlet>
<servlet-name>Faces Servlet</servlet-name>
<servlet-class>javax.faces.webapp.FacesServlet</servlet-class>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>Faces Servlet</servlet-name>
<url-pattern>/faces/*</url-pattern>
<url-pattern>/javax.faces.resource/*</url-pattern>
</servlet-mapping>
托管豆
package com.teaman.bean;
import java.io.Serializable;
import javax.enterprise.context.SessionScoped;
import javax.faces.context.FacesContext;
import javax.faces.event.ComponentSystemEvent;
import javax.inject.Named;
import org.apache.log4j.Logger;
@Named(value = "teaManUserSessionBean")
@SessionScoped
public class TeaManUserSessionBean implements Serializable {
....
public void initUserSession(ComponentSystemEvent e) {
logger.debug("TeaManUserSession init...");
}
....
}
也许有人已经遇到过同样的问题,可以帮助我们吗? :) 非常感谢您的每一个提示/注释/评论。
【问题讨论】:
-
什么是 Spring CDI? - 我知道 Spring (DI) 和 CDI,但不知道 Spring CDI
-
应该有 Spring + CDI + JSF ...我的错误,对不起。
-
使用 Spring 和 CDI 有什么好的理由吗? - 如果不是,我强烈建议只使用其中一个(如果你也想使用 Spring-Secruity,我会选择 Spring)。
-
jsf 托管 bean 怎么样?我读到如果我们想在 spring 中使用 jsf,我们应该使用 CDI(@Named 等)。清除 jsf 托管 bean 不能与 spring 层一起正常工作。
-
Spring 的默认作用域是应用程序作用域。所以我猜想 bean 管理配置出了点问题,你的支持 bean 实际上被视为 Spring 托管 bean 而不是 CDI 托管 bean。相关:*.com/q/18387993
标签: spring spring-security cdi managed-bean