18

我将 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。我用萤火虫检查了请求的数量。有树请求:

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

2 回答 2

22

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

如果您使用 CDI 并且@Named在整个课程中使用多个注释,也会发生这种情况。例如,一个@Named直接在类上将其注册为托管 bean,另一个在@Producesgetter 方法上。你需要问问自己这是否真的有必要。您也可以只使用#{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();

}
于 2012-01-31T12:13:24.447 回答
2

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

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

我还在这里找到了一篇关于调试 JSF 生命周期的好帖子: 调试 JSF 生命周期

于 2012-01-31T10:50:37.730 回答