为 JSF 中的生命周期方法子集调用侦听器



在实现PhaseListener接口的 jsf bean 中,beforePhaseafterPhase方法只会在方法指示的阶段之前和之后调用getPhaseId。此机制仅允许我们只选择一个阶段,这两个方法将在之前和之后调用。
有没有办法告诉JSF在生命周期方法的子集(不仅仅是一个)上调用这两个方法(beforePhaseafterPhase

)。
  1. 还原视图
  2. 应用请求值
  3. 工艺验证
  4. 更新模型值
  5. 调用应用程序
  6. 渲染响应阶段

)

public class HelloBean implements PhaseListener {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void afterPhase(PhaseEvent phaseEvent) {
System.out.println("after phase "+phaseEvent.getPhaseId());
}
@Override
public void beforePhase(PhaseEvent phaseEvent) {
System.out.println("beforePhase "+phaseEvent.getPhaseId());
}
public void testMethod(){
System.out.println("Test Method");
}
@Override
public PhaseId getPhaseId() {
return PhaseId.RESTORE_VIEW;
}
}

不幸的是,这是不可能的。作为通用解决方法,您可以实现自定义扩展的 PhaseListener,如下所示:

public interface MultiplePhasesListener extends PhaseListener {
@Override
default void beforePhase(PhaseEvent phaseEvent) {
if (processPhase(phaseEvent.getPhaseId())) {
beforePhases(phaseEvent);
}
}
@Override
default void afterPhase(PhaseEvent phaseEvent) {
if (processPhase(phaseEvent.getPhaseId())) {
afterPhases(phaseEvent);
}
}
@Override
default PhaseId getPhaseId() {
return PhaseId.ANY_PHASE;
}
default boolean processPhase(PhaseId phaseId) {
if (phaseId == null) {
return false;
}
List<PhaseId> phaseIds = getPhaseIds();
if (phaseIds == null || phaseIds.isEmpty()) {
return false;
}
return phaseIds.contains(phaseId);
}
void beforePhases(PhaseEvent phaseEvent);
void afterPhases(PhaseEvent phaseEvent);
List<PhaseId> getPhaseIds();
}

并像这样使用它:

public class MultiplePhasesListenerImpl implements MultiplePhasesListener {
private static final long serialVersionUID = 1877176187821557447L;
@Override
public void beforePhases(PhaseEvent phaseEvent) {
System.out.println(phaseEvent.getPhaseId());
}
@Override
public void afterPhases(PhaseEvent phaseEvent) {
System.out.println(phaseEvent.getPhaseId());
}
@Override
public List<PhaseId> getPhaseIds() {
return Arrays.asList(PhaseId.APPLY_REQUEST_VALUES, PhaseId.RENDER_RESPONSE);
}
}  

请注意,在任何阶段之前和之后调用 PhaseListener 方法,但逻辑仅在所需阶段之前和之后处理。

此外,请注意,MultiplePhasesListener 接口的实现使用默认方法,这些方法属于 Java 8。如果您使用较低的Java版本,则可以使用抽象类而不是接口,并扩展该抽象类的PhaseListener实现。缺点是您无法再从另一个类扩展。