@PostConstruct 方法针对同一请求调用两次
我将 JSF 2.0 与 GlassFish 3.0 结合使用。
我有以下托管 Bean:
@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");
}
}
从 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
如您所见, init() 方法在同一个请求中无缘无故地被调用了两次。据我所知,任何用 PostConstruct 注释的方法每个请求都会调用一次。我错了吗?
编辑: 页面上没有使用AJAX。 我用 firebug 检查了请求数。发出了树请求:
- 1.一个用于 javax.faces.resource (GET)
- 2.一个用于 css 文件 (GET)
- 3.一个用于overview.xhtml (获取)
I'm using JSF 2.0 with GlassFish 3.0.
I have the following Managed Bean:
@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");
}
}
From the the overview.xhtml file I'm calling different attributes or methods from my OverviewController.
<ui:repeat var="event" value="#{overviewController.eventList}">
...
</ui:repeat>
Everything works just fine but the problem is on the Log File:
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
As you can see, The init() method is called twice in the same request for no reason what so ever. From what I know, any method annotated with PostConstruct is called once every request. Am I wrong?
EDIT:
No AJAX is used on the page.
I checked the number of requests with firebug. There are tree requests made:
- 1.One for the javax.faces.resource (GET)
- 2.One for the css file (GET)
- 3.One for overview.xhtml (GET)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您有多个框架管理同一个 bean 类,则可能会发生这种情况。例如,JSF 和 CDI,或 JSF 和 Spring,或 CDI 和 Spring 等。仔细检查 bean 上的配置和注释。
如果您使用 CDI 并在整个类中使用多个
@Named
注释,也可能会发生这种情况。例如,直接在类上使用@Named
将其注册为托管 bean,而在@Produces
getter 方法上使用另一个 @Named。您需要问自己这是否真的有必要。您也可以只使用#{bean.someObject}
而不是#{someObject}
。如果您的托管 bean 扩展了某个抽象类,而该抽象类在方法上又具有
@PostConstruct
,那么也可能会发生这种情况。您应该从中删除注释。或者,您应该将 init 方法设为抽象,并且在实现 bean 上不使用@PostConstruct
:That can happen if you have multiple frameworks managing the same bean class. E.g. JSF and CDI, or JSF and Spring, or CDI and Spring, etc. Doublecheck your configuration and annotations on the bean.
That can also happen if you're using CDI and are using multiple
@Named
annotations throughout the class. For example, a@Named
straight on the class to register it as a managed bean and another one on a@Produces
getter method. You'd need to ask yourself whether that is really necessary. You could also just use#{bean.someObject}
instead of#{someObject}
.That can also happen if your managed bean extends some abstract class which has in turn also a
@PostConstruct
on the method. You should remove the annotation from it. Alternatively, you should make the init method abstract and not have@PostConstruct
on the implementing bean:init()
方法和@PostConstruct
方法可能都会触发并导致此行为。尝试更改init()
方法的名称和/或将其设置为private
。我认为这可能与您的问题有关:http: //javahowto.blogspot.com/2011/07/servlet-init-method-vs-postconstruct.html
我还在这里找到了一篇关于调试 JSF 生命周期的好文章:
调试 JSF 生命周期
It is possible that the both
init()
method and@PostConstruct
methods are firing and causing this behavior. Try changing the name of theinit()
method and/or putting itprivate
. I think that this may be related to your problems:http://javahowto.blogspot.com/2011/07/servlet-init-method-vs-postconstruct.html
I also found a good post about debugging JSF life cycles here:
Debug JSF lifecycle