我正在开发一个使用 JSF 1.2 的 JSR-286 portlet 应用程序。我正在努力将我的 JSF 托管 bean 移动到 Spring bean,我注意到 Spring 如何处理请求范围与 JSF 如何处理请求范围之间似乎存在差异。
在我的 portlet 应用程序中,我有两个 portlet 位于同一页面上,并且都使用相同的起始 JSF portlet 页面视图。当我使用 JSF 托管请求 bean 时,会为每个 portlet 创建一个单独的请求 bean,这就是我要寻找的行为。当我使用 Spring bean 时,只会创建一个请求 bean,并在两个 portlet 之间共享。这是正常行为吗?有什么办法可以阻止它这样做吗?
在将我的 bean 移动到 Spring 之前,我原来的 faces-config.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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/web-facesconfig_1_2.xsd"
version="1.2">
<application>
<state-manager>com.ibm.faces.application.DevelopmentStateManager</state-manager>
<variable-resolver>com.ibm.faces.portlet.PortletVariableResolver</variable-resolver>
</application>
<factory>
<faces-context-factory>com.ibm.faces.context.AjaxFacesContextFactory</faces-context-factory>
<render-kit-factory>com.ibm.faces.renderkit.AjaxRenderKitFactory</render-kit-factory>
</factory>
<managed-bean>
<managed-bean-name>sessionBean</managed-bean-name>
<managed-bean-class>sanitycheck.SessionBean</managed-bean-class>
<managed-bean-scope>session</managed-bean-scope>
</managed-bean>
<managed-bean>
<managed-bean-name>pc_SanityCheckProjectView</managed-bean-name>
<managed-bean-class>sanitycheck.SanityCheckProjectView</managed-bean-class>
<managed-bean-scope>request</managed-bean-scope>
<managed-property>
<property-name>sessionBean</property-name>
<value>#{sessionBean}</value>
</managed-property>
</managed-bean>
<lifecycle>
<phase-listener>com.ibm.faces.webapp.ValueResourcePhaseListener</phase-listener>
</lifecycle>
</faces-config>
将 bean 移动到 Spring 后我的 faces-config.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<faces-config
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/web-facesconfig_1_2.xsd"
version="1.2">
<application>
<state-manager>com.ibm.faces.application.DevelopmentStateManager</state-manager>
<variable-resolver>com.ibm.faces.portlet.PortletVariableResolver</variable-resolver>
<variable-resolver>org.springframework.web.jsf.DelegatingVariableResolver</variable-resolver>
</application>
<factory>
<faces-context-factory>com.ibm.faces.context.AjaxFacesContextFactory</faces-context-factory>
<render-kit-factory>com.ibm.faces.renderkit.AjaxRenderKitFactory</render-kit-factory>
</factory>
<lifecycle>
<phase-listener>com.ibm.faces.webapp.ValueResourcePhaseListener</phase-listener>
</lifecycle>
</faces-config>
还有我的 spring-web.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:aop="http://www.springframework.org/schema/aop"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-2.0.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop-2.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-2.0.xsd">
<bean id="sessionBean" class="sanitycheck.SessionBean" scope="session">
<aop:scoped-proxy/>
</bean>
<bean id="pc_SanityCheckProjectView" class="pagecode.SanityCheckProjectView" scope="request" init-method="init">
<aop:scoped-proxy/>
<property name="sessionBean" ref="sessionBean"/>
</bean>
</beans>
如有必要,我可以提供我的其他文件,请告诉我。谢谢!
编辑:将 aop:scoped-proxy 添加到 Spring bean。
编辑:添加 portlet.xml 文件:
<?xml version="1.0" encoding="UTF-8"?>
<portlet-app xmlns="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd http://java.sun.com/xml/ns/portlet/portlet-app_2_0.xsd" id="com.ibm.faces.portlet.FacesPortlet.3a22ca3014">
<portlet>
<portlet-name>SanityCheckProject</portlet-name>
<display-name xml:lang="en">SanityCheckProject</display-name>
<display-name>SanityCheckProject</display-name>
<portlet-class>com.ibm.faces.portlet.FacesPortlet</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/SanityCheckProjectView.jsp</value>
</init-param>
<init-param>
<name>whichOne</name>
<value>Portlet1</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.ibm.sanitycheckproject.nl.SanityCheckProjectPortletResource</resource-bundle>
<portlet-info>
<title>SanityCheckProject</title>
<short-title>SanityCheckProject</short-title>
<keywords>SanityCheckProject</keywords>
</portlet-info>
</portlet>
<portlet>
<portlet-name>SanityCheckPortlet2</portlet-name>
<display-name xml:lang="en">SanityCheckPortlet2</display-name>
<display-name>SanityCheckPortlet2</display-name>
<portlet-class>com.ibm.faces.portlet.FacesPortlet</portlet-class>
<init-param>
<name>com.ibm.faces.portlet.page.view</name>
<value>/SanityCheckProjectView.jsp</value>
</init-param>
<init-param>
<name>whichOne</name>
<value>Portlet2</value>
</init-param>
<init-param>
<name>wps.markup</name>
<value>html</value>
</init-param>
<expiration-cache>0</expiration-cache>
<supports>
<mime-type>text/html</mime-type>
<portlet-mode>view</portlet-mode>
</supports>
<supported-locale>en</supported-locale>
<resource-bundle>com.ibm.sanitycheckproject.nl.SanityCheckPortlet2PortletResource</resource-bundle>
<portlet-info>
<title>SanityCheckPortlet2</title>
<short-title>SanityCheckPortlet2</short-title>
<keywords>SanityCheckPortlet2</keywords>
</portlet-info>
</portlet>
<default-namespace>http://SanityCheckProject/</default-namespace>
</portlet-app>