@PostConstruct方法为同一请求调用两次

时间:2012-01-31 10:28:05

标签: java jsf jsf-2 postconstruct

我正在使用带有GlassFish 3.0的JSF 2.0。

我有以下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");
    }
}

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.One for overview.xhtml (GET)

2 个答案:

答案 0 :(得分:21)

如果您有多个框架来管理同一个bean类,那么就会发生这种情况。例如。 JSF CDI,或JSF Spring,或CDI Spring等。仔细检查bean上的配置和注释。

如果您正在使用CDI并且在整个班级中使用多个@Named注释,也会发生这种情况。例如,类@Named直接在类上注册它作为托管bean,另一个注册在@Produces getter方法上。你需要问问自己这是否真的 。您也可以使用#{bean.someObject}代替#{someObject}

@Named
@RequestScoped
public class Bean {

    @PostConstruct
    public void init() {
        // ...
    }

    @Named
    @Produces
    public SomeObject getSomeObject() {
        // ...
    }

}

如果您的托管bean扩展了一些抽象类,并且该方法上还有@PostConstruct,那么也会发生这种情况。您应该从中删除注释。或者,您应该在实现bean上使init方法变为抽象而具有@PostConstruct

public abstract class BaseBean {

    @PostConstruct
    public void postConstruct() {
        init();
    }

    public abstract void init();

}

答案 1 :(得分:2)

init()方法和@PostConstruct方法都可能会触发并导致此行为。尝试更改init()方法的名称和/或将其private。我认为这可能与您的问题有关:

http://javahowto.blogspot.com/2011/07/servlet-init-method-vs-postconstruct.html

我还在这里找到了关于调试JSF生命周期的好文章: Debug JSF lifecycle