I need to share an attribute between the beforePhase() and the afterPhase() methods of my PhaseListener, for a same JSF request.
Is the following snippet thread-safe?
public class MyPhaseListener implements PhaseListener {
private MyObject o = null;
@Override
public void beforePhase(PhaseEvent event) {
if (condition) {
o = new MyObject();
}
}
@Override
public void afterPhase(PhaseEvent event) {
if (o != null) {
o.process();
o = null;
}
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}
If not, what are other solutions?
This is definitely not threadsafe. There's only one phase listener instance applicationwide which is shared across multiple requests. Basically, a phase listener is like an @ApplicationScoped
managed bean.
Just set it as a context attribute.
public class MyPhaseListener implements PhaseListener {
@Override
public void beforePhase(PhaseEvent event) {
if (condition) {
event.getFacesContext().setAttribute("o", new MyObject());
}
}
@Override
public void afterPhase(PhaseEvent event) {
MyObject o = (MyObject) event.getFacesContext().getAttribute("o");
if (o != null) {
o.process();
}
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}