I have two ManagedBeans
(@SessionScoped
and @ViewScoped
):
@ManagedBean(name="sessionController")
@SessionScoped
public class SessionController implements Serializable{
private PropertyChangeSupport propertyChangeSupport = new PropertyChangeSupport(this);
public void addPropertyChangeListener(PropertyChangeListener listener) {
propertyChangeSupport.addPropertyChangeListener(listener);
}
...
}
@ManagedBean(name="viewController")
@ViewScoped
public class ViewController implements Serializable, PropertyChangeListener{
@ManagedProperty(value="#{sessionController}")
private SessionController sessionController ;
...
@PostConstruct
public void init() {
sessionController.addPropertyChangeListener(this);
}
@Override
public void propertyChange(PropertyChangeEvent evt) {
...
}
}
Can I use PropertyChangeListener
in ViewController
to know about changes in SessionController
? Will there be any problems?
No you can't. To add PropertyChangeSupport
to the @SessionScoped
bean, you need to call
propertyChangeSupport.addPropertyChangeListener("instanceofViewScopedBean")
at a convenient spot (preferably the @PostConstructor
). Note that you require an actual instance of the target bean (implementing PropertyChangeListener
) to pass to the addPropertyChangeListener
. As far as I can tell, You cannot get this from within the session bean, especially at bean initialization. Why? well it's viewscoped, it only lives as long as a page is being viewed.
Related to this restriction is the JSF policy that Managed Beans can only be injected into other beans of a narrower scope (using your case, only the session bean can be injected into the viewscoped bean). What you're looking to do amounts to pretty much the opposite, tying a viewscoped bean to a session scoped variable.
I presume you're trying to achieve a low-cost server-side push mechanism. Well, I don't know of another means to get this done apart from good ol' polling or comet pushing.