I instantiated a request bean from another request bean,
new LoginManager();
But the property which is annotated with @ManagedProperty
doesn't get the value from the asked reference, only in case of instantiation through the above way. It just contains null
, causing NPE later in code. Also @PostConstruct
won't be invoked. Why is it so & how should I deal with this?
@ManagedBean(name = "loginManager")
@RequestScoped
public class LoginManager {
private String userid;
private String password;
@ManagedProperty(value="#{currentSession}")
private UserSessionManager userSession;
}
But userSession
can't read from the session scoped bean when this bean was instantiated using: new LoginManager();
However I can read the value using FacesContext
!
You should not manually instantiate (manage) beans using new
operator. You should let JSF do the job of managing the beans and instead grab the JSF-managed (JSF-instantiated) instance.
Either by @ManagedProperty
in the bean where you need it:
@ManagedProperty("#{loginManager}")
private LoginManager loginManager;
Or by invoking EL programmatically (which is pretty borderline in your particular case):
LoginManager loginManager = context.getApplication().evaluateExpressionGet(context, "#{loginManager}", LoginManager.class);
// ...
If you insist in instantiating and managing the bean yourself, you should do all dependency injections yourself, also invoking the @PostConstruct
yourself, if any, and finally also putting the bean in the desired scope yourself. E.g.
LoginManager loginManager = new LoginManager();
loginManager.setUserSession(userSession);
// Now use reflection to find and invoke @PostConstruct method.
// Finally store in the map which conforms the bean's scope.
externalContext.getRequestMap().put("loginManager", loginManager);
This boilerplate is exactly what JSF is supposed to take away from your hands. Make use of it.