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

Ion*_*nut 17 java jsf postconstruct jsf-2

我正在使用JSF 2.0和GlassFish 3.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");
    }
}
Run Code Online (Sandbox Code Playgroud)

overview.xhtml文件中,我从OverviewController中调用了不同的属性或方法.

<ui:repeat var="event" value="#{overviewController.eventList}">
    ...
</ui:repeat>
Run Code Online (Sandbox Code Playgroud)

一切正常,但问题出在日志文件中:

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
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,init()方法在同一个请求中被调用两次,没有任何理由.据我所知,每个请求都会调用一次使用PostConstruct注释的方法.我错了吗?

编辑: 页面上没有使用AJAX.我用firebug检查了请求的数量.有树请求:

  • 1.一个用于javax.faces.resource (GET)
  • 2.一个用于css文件(GET)
  • 3.One for overview.xhtml (GET)

Bal*_*usC 21

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

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

@Named
@RequestScoped
public class Bean {

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

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

}
Run Code Online (Sandbox Code Playgroud)

如果您的托管bean扩展了一些抽象类,而后者也@PostConstruct依赖于该方法,那么也会发生这种情况.您应该从中删除注释.另外,你应该让init方法抽象的,具有@PostConstruct对实现bean:

public abstract class BaseBean {

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

    public abstract void init();

}
Run Code Online (Sandbox Code Playgroud)

  • 谢谢!我没有多个框架,但这有助于我理解问题所在.我的所有ManagedBeans都扩展了一个`BaseController`.这个BaseController有一个`@PostConstruct init()`方法,我认为它会被其他ManagedBeans的'PostConstruct init()`覆盖.似乎两个`init()`都被调用了.这一切都有意义..谢谢! (2认同)