我在Tomcat 7下运行了一个JSF webapp(Mojarra 2.2.12,PrimeFaces 5.2,OmniFaces 2.2)(我按照这些步骤安装了CDI:http://balusc.omnifaces.org/2013/10/how-to-install-cdi-in-tomcat.html)。
我正在尝试使用@ManagedBean
注释将我的JSF bean转换为带有@Named
注释的CDI bean。我的问题是每当我使用@Named注释一个bean时,即使它有@ViewScoped注释,它也会在webapp启动时获得实例化。要找出错误,我已将下面的3个bean添加到webapp(灵感来自http://showcase.omnifaces.org/cdi/ViewScoped)
“纯粹的”JSF bean
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ViewScoped;
import org.omnifaces.util.Faces;
@ManagedBean
@ViewScoped
public class JsfViewScopedBean implements Serializable {
private static final long serialVersionUID = 1L;
@PostConstruct
public void postConstruct() {
System.out.println(getClass().getSimpleName()
+ ".postConstruct() invoked");
}
public void submit() {
System.out.println(getClass().getSimpleName() + ".submit() invoked");
}
public String navigate() {
System.out.println(getClass().getSimpleName() + ".navigate() invoked");
return Faces.getViewId();
}
public void rebuildView() {
System.out.println(getClass().getSimpleName()
+ ".rebuildView() invoked");
Faces.setViewRoot(Faces.getViewId());
}
@PreDestroy
public void preDestroy() {
System.out
.println(getClass().getSimpleName() + ".preDestroy() invoked");
}
}
带有javax.faces.view.ViewScoped注释的CDI bean
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.faces.view.ViewScoped;
import javax.inject.Named;
import org.omnifaces.util.Faces;
@Named
@ViewScoped
public class CdiJsfViewScopedBean implements Serializable {
private static final long serialVersionUID = 1L;
@PostConstruct
public void postConstruct() {
System.out.println(getClass().getSimpleName()
+ ".postConstruct() invoked");
}
public void submit() {
System.out.println(getClass().getSimpleName() + ".submit() invoked");
}
public String navigate() {
System.out.println(getClass().getSimpleName() + ".navigate() invoked");
return Faces.getViewId();
}
public void rebuildView() {
System.out.println(getClass().getSimpleName()
+ ".rebuildView() invoked");
Faces.setViewRoot(Faces.getViewId());
}
@PreDestroy
public void preDestroy() {
System.out
.println(getClass().getSimpleName() + ".preDestroy() invoked");
}
}
带有org.omnifaces.cdi.ViewScoped注释的CDI bean
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
import javax.inject.Named;
import org.omnifaces.cdi.ViewScoped;
import org.omnifaces.util.Faces;
@Named
@ViewScoped
public class CdiOmnifacesViewScopedBean implements Serializable {
private static final long serialVersionUID = 1L;
@PostConstruct
public void postConstruct() {
System.out.println(getClass().getSimpleName()
+ ".postConstruct() invoked");
}
public void submit() {
System.out.println(getClass().getSimpleName() + ".submit() invoked");
}
public String navigate() {
System.out.println(getClass().getSimpleName() + ".navigate() invoked");
return Faces.getViewId();
}
public void rebuildView() {
System.out.println(getClass().getSimpleName()
+ ".rebuildView() invoked");
Faces.setViewRoot(Faces.getViewId());
}
@PreDestroy
public void preDestroy() {
System.out
.println(getClass().getSimpleName() + ".preDestroy() invoked");
}
}
当我启动webapp时,应用程序范围bean按预期进行了解释,但是CdiJsfViewScopedBean和CdiOmnifacesViewScopedBean也是实例化的,因为我在日志中获得了这些行:
CdiJsfViewScopedBean.postConstruct() invoked
CdiOmnifacesViewScopedBean.postConstruct() invoked
从一开始就显然出现了问题...我已经添加了一个网页来调查我的bean的行为(正如@BalusC在他的展示中所做的那样)并且事实证明JsfViewScopedBean的行为与BalusC的行为完全相同展示,但那些带有@Named注释的2,无论我按什么按钮都不会再次实现...
这是网页:
<ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:h="http://java.sun.com/jsf/html"
xmlns:f="http://java.sun.com/jsf/core" xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.org/ui" xmlns:c="http://java.sun.com/jsp/jstl/core"
template="/templates/resosLayout.xhtml">
<ui:define name="content">
<h3>JsfViewScopedBean</h3>
<h:form id="jsfViewScopedBeanForm">
<p>Status:</p>
<ul>
<li>It's now: #{now}</li>
<li>Session ID: #{session.id}</li>
<li>JSF view scoped bean: #{jsfViewScopedBean}</li>
</ul>
<p>
<h:commandButton value="submit form without ajax" action="#{jsfViewScopedBean.submit}" />
<h:commandButton value="submit form with ajax" action="#{jsfViewScopedBean.submit}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:commandButton value="rebuild view" action="#{jsfViewScopedBean.rebuildView}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:commandButton value="navigate on POST" action="#{jsfViewScopedBean.navigate}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:button value="refresh page" />
</p>
<p>Messages from jsfViewScopedBeanForm:</p>
<h:messages for="jsfViewScopedBeanForm" />
</h:form>
<hr />
<h3>CdiJsfViewScopedBean</h3>
<h:form id="cdiJsfViewScopedBeanForm">
<p>Status:</p>
<ul>
<li>It's now: #{now}</li>
<li>Session ID: #{session.id}</li>
<li>JSF view scoped bean: #{cdiJsfViewScopedBean}</li>
</ul>
<p>
<h:commandButton value="submit form without ajax" action="#{cdiJsfViewScopedBean.submit}" />
<h:commandButton value="submit form with ajax" action="#{cdiJsfViewScopedBean.submit}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:commandButton value="rebuild view" action="#{cdiJsfViewScopedBean.rebuildView}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:commandButton value="navigate on POST" action="#{cdiJsfViewScopedBean.navigate}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:button value="refresh page" />
</p>
<p>Messages from cdiJsfViewScopedBeanForm:</p>
<h:messages for="cdiJsfViewScopedBeanForm" />
</h:form>
<hr />
<h3>CdiOmnifacesViewScopedBean</h3>
<h:form id="cdiOmnifacesViewScopedBeanForm">
<p>Status:</p>
<ul>
<li>It's now: #{now}</li>
<li>Session ID: #{session.id}</li>
<li>JSF view scoped bean: #{cdiOmnifacesViewScopedBean}</li>
</ul>
<p>
<h:commandButton value="submit form without ajax" action="#{cdiOmnifacesViewScopedBean.submit}" />
<h:commandButton value="submit form with ajax" action="#{cdiOmnifacesViewScopedBean.submit}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:commandButton value="rebuild view" action="#{cdiOmnifacesViewScopedBean.rebuildView}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:commandButton value="navigate on POST" action="#{cdiOmnifacesViewScopedBean.navigate}">
<f:ajax execute="@form" render="@form" />
</h:commandButton>
<h:button value="refresh page" />
</p>
<p>Messages from CdiOmnifacesViewScopedBean:</p>
<h:messages for="cdiOmnifacesViewScopedBeanForm" />
</h:form>
</ui:define>
</ui:composition>
我的猜测是,我要么错过了CDI bean,要么我的CDI设置有问题,或者可能与其他libs有些冲突(我使用spring)但是我不知道从哪里开始排序...
答案 0 :(得分:0)
最后我解决了(非常感谢@Kukeltje,你把我放在正确的轨道上)但是我真的不明白整个事情......
这是春天的一个问题:在我的webapp的spring配置文件中,我有:
<context:component-scan base-package="org.sarcomabcb.resos.web" />
当我将3个bean移动到spring未扫描的目录时,它们突然开始按预期运行。
可能会帮助像我这样的新手...