Reputation: 1117
I had a request-scoped JSF 1.2 managed bean that I needed to refactor to session-scoped bean because it is doing some expensive operation on @PostConstruct
and that is being called multiple times which really needs to be done only once. The side effect of changing the scope to session is now I cannot inject FacesContext
anymore in faces-config.xml
by doing like this:
<managed-property>
<property-name>context</property-name>
<value>#{facesContext}</value>
</managed-property>
where I have
setContext(FacesContext ctx) {}
in my managed bean.
In one of my action methods I need the context to access ExternalContext
/HttpServletResponse
. I don't want to invoke
FacesContext.getCurrentInstance();
inside my action method but somehow call setContext(FacesContext ctx)
externally to allow isolation of context injection for ease of mocked testing. I tried putting the setContext()
inside the @PostConstruct
only to realize later that FacesContext
is a per request thing and my ExternalContext
was reset to null
once a new request is being submitted.
How could I call setContext(FacesContext ctx)
auto-magically every time I hit a new request although the managed bean itself is session scoped?
Upvotes: 2
Views: 3949
Reputation: 1108537
Keep your request scoped bean and inject the session scoped bean in it instead so that you can pass the FacesContext
to it in the @PostConstruct
of the request scoped bean. In the session scoped bean, perform lazy loading/executing.
E.g.
public class RequestBean {
private FacesContext context; // Managed property.
private SessionBean sessionBean; // Managed property.
@PostConstruct
public void init() {
sessionBean.init(context);
}
// ...
}
and
public class SessionBean {
private SomeObject initializedObject;
public void init(FacesContext context) {
if (initializedObject != null) {
return;
}
initializedObject = initializeObject(context);
}
// ...
}
Upvotes: 1