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:
2. @PostConstruct. Spring calls the methods annotated with @PostConstruct only once, just after the initialization of bean properties.
In a single class, it allows to have more than one @PostConstruct annotated method, and also the order of execution is random.
Correct? Despite you use asynchronized method, these postConstruct methods wil be executed sequentially. Then, ServiceA#init() will be finished when ServiceB#init() will begin.
The PostConstruct annotation is used on a method that needs to be executed after dependency injection is done to perform any initialization. This method MUST be invoked before the class is put into service. This annotation MUST be supported on all classes that support dependency injection.
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}
.
@Named
@RequestScoped
public class Bean {
@PostConstruct
public void init() {
// ...
}
@Named
@Produces
public SomeObject getSomeObject() {
// ...
}
}
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:
public abstract class BaseBean {
@PostConstruct
public void postConstruct() {
init();
}
public abstract void init();
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With