Java @为同一请求调用了两次PostConstruct方法
我将JSF2.0与GlassFish 3.0结合使用 我有以下托管Bean:Java @为同一请求调用了两次PostConstruct方法,java,jsf,jsf-2,postconstruct,Java,Jsf,Jsf 2,Postconstruct,我将JSF2.0与GlassFish 3.0结合使用 我有以下托管Bean: @ManagedBean @RequestScoped public class OverviewController{ private List<Event> eventList; @PostConstruct public void init(){ System.out.println("=> OverviewController - init() -
@ManagedBean
@RequestScoped
public class OverviewController{
private List<Event> eventList;
@PostConstruct
public void init(){
System.out.println("=> OverviewController - init() - enter");
System.out.println("=< OverviewController - init() - exit");
}
}
@ManagedBean
@请求范围
公共类概览控制器{
私有列表事件列表;
@施工后
公共void init(){
System.out.println(“=>OverviewController-init()-enter”);
System.out.println(“=
在overview.xhtml文件中,我从OverviewController调用了不同的属性或方法
<ui:repeat var="event" value="#{overviewController.eventList}">
...
</ui:repeat>
...
一切正常,但问题出在日志文件上:
INFO: Enter : RESTORE_VIEW 1
INFO: Exit : RESTORE_VIEW 1
INFO: Enter : RENDER_RESPONSE 6
INFO: => OverviewController - init() - enter
INFO: => Overview Controller - updateSelectedTab() - enter
INFO: =< Overview Controller - updateSelectedTab() - exit
INFO: =< OverviewController - init() - exit
INFO: => OverviewController - init() - enter
INFO: => Overview Controller - updateSelectedTab() - enter
INFO: =< Overview Controller - updateSelectedTab() - exit
INFO: =< OverviewController - init() - exit
INFO: Exit : RENDER_RESPONSE 6
INFO:Enter:RESTORE\u视图1
信息:退出:还原视图1
信息:输入:渲染_响应6
信息:=>概览控制器-init()-输入
信息:=>概览控制器-更新选定选项卡()-输入
信息:=概览控制器-init()-输入
信息:=>概览控制器-更新选定选项卡()-输入
信息:=
正如您所看到的,init()方法在同一个请求中被调用了两次,没有任何原因。据我所知,任何带有PostConstruct注释的方法都会在每个请求中调用一次。我错了吗
编辑:
页面上没有使用AJAX。
我用firebug检查了请求的数量。有三个请求:
- 1.一个用于javax.faces.resource(GET)
- 2.一个用于css文件(GET)
- 3.一个用于overview.xhtml(GET)
init()
方法和@PostConstruct
方法都在触发并导致此行为。尝试更改init()
方法的名称和/或将其设置为private
。我认为这可能与你的问题有关:
我还发现了一篇关于调试JSF生命周期的好文章:
如果有多个框架管理同一个bean类,可能会发生这种情况。例如JSF和CDI,或者JSF和Spring,或者CDI和Spring,等等。仔细检查bean上的配置和注释 如果您使用CDI并且在整个类中使用多个
@Named
注释,也可能发生这种情况。例如,类上直接命名为的@将其注册为托管bean,而@上的另一个将生成
getter方法。你需要问问自己这是否真的有必要。您也可以只使用{bean.someObject}
而不是{someObject}
@Named
@RequestScoped
public class Bean {
@PostConstruct
public void init() {
// ...
}
@Named
@Produces
public SomeObject getSomeObject() {
// ...
}
}
如果托管bean扩展了某个抽象类,而该抽象类在方法上又有一个@PostConstruct
,也会发生这种情况。您应该从中删除注释。或者,您应该使init方法抽象,并且在实现bean上没有@PostConstruct
:
public abstract class BaseBean {
@PostConstruct
public void postConstruct() {
init();
}
public abstract void init();
}
你是说ClassFish还是GlassFish?你在执行Ajax调用吗?使用FireBug或类似的附加组件来找出浏览器实际发出了多少请求。@PederN我更新了这个问题。在这个页面上有一些调试JSF生命周期的提示。看看吧,也许有什么东西可以帮你,谢谢!遗憾的是,我找不到任何可以解释我问题的东西。似乎所有用@PostConstruct注释的方法都在Invoke应用程序或RenderResponseThis中被调用了两次,这毫无意义。JSF管理的bean不是一个HttpServlet
实现。我的意思是,根据配置的不同,它可能会导致系统混淆,并在这两种方法上启动。也许这是一个漫长的过程。谢谢你的澄清。我试图删除注释,但是init()将被忽略。正如BalusC所说,托管bean中似乎没有init()方法。@Peder:JSF对名为init()
的方法绝对没有特殊处理。您混淆了HttpServlet#init()
。请重新阅读您自己链接的javahowto文章。谢谢!我没有多个框架,但这帮助我理解了问题所在。我所有的ManagedBeans都扩展了一个BaseController
。此BaseController有一个@PostConstruct init()
方法,我认为其他ManagedBeans的PostConstruct init()
会覆盖该方法。似乎两个init()
都被调用了。现在一切都有道理了。。非常感谢。在BaseController
类中不应该有@PostConstruct
。把它拿走。@BalusC:我有个小问题。关于在同一个bean上使用JSF和CDI,如果我使用@Inject
将CDIBean注入@ManagedBean
,会调用@PostConstruct
方法两次吗?我不太确定如何在同一个bean上应用多个框架。我认为该框架是由使用@ManagedBean
,@Named
等注释bean决定的。BalusC我也有同样的问题。我在@Controller
类中定义了@PostConstruct
方法。有什么问题吗?实际上,我想启动我的应用程序部署计划程序。还有别的办法吗?