(请先看看源代码)


一开始,我不停地往同一个页面发送请求,发现那些监听器越来越多,我还以为虽然是RequestScope的,但是JSF中的bean还是不自己注销才而又不停的产生,才搞到监听器越来越多。后来才发现,每次关掉浏览器的时候,bean已经注销的了,只是监听器还在那里,结果每次产生bean的时候又注册监听器,搞到监听器越来越多。
后来经过多番“调查研究”,才知道,phaseListener是针对整个应用的lifeCycle的(lifeCycle是不是整个应用只有一个的啊??),所以,即使注册那个监听器的bean被销毁了,那个监听器还在那儿,所以每次重新构造一个那个bean的时候,又重新构造了监听器。。所以就搞得重复向页面发送请求的时候,阶段监听器(PhaseListener)会越来越多!

下面是页面代码,通过按state1按钮来:
<%@page contentType="text/html"%>
<%@page pageEncoding="UTF-8"%>

<%@taglib prefix="f" uri="http://java.sun.com/jsf/core"%>
<%@taglib prefix="h" uri="http://java.sun.com/jsf/html"%>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"
"http://www.w3.org/TR/html4/loose.dtd">

<%--
        This file is an entry point for JavaServer Faces application.
--%>

<f:view>
        <f:loadBundle basename="lr.LR" var="lr"/>
        <html>
                <head>
                        <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
                        <title>JSP Page</title>
                </head>
                <body>
                        <h:message for="mboxs"/>
                        <h:form id="form1">
                                <h:selectManyCheckbox id="mboxs" required="true" binding="#{welcomeJSFbean.mboxs}" border="1" layout="pageDirection">
                                        <f:selectItem itemValue="dogs" itemLabel="#{lr.dogs}"/>
                                        <f:selectItem itemValue="cats" itemLabel="#{lr.cats}"/>
                                        <f:selectItem itemValue="snakes" itemLabel="#{lr.snakes}"/>
                                        <f:selectItem itemValue="rabbits" itemLabel="#{lr.rabbits}"/>
                                        <f:selectItem itemValue="lions" itemLabel="#{lr.lions}"/>
                                        <f:selectItem itemValue="tigers" itemLabel="#{lr.tigers}"/>
                                </h:selectManyCheckbox>
                                <h:commandButton value="next" action="#{welcomeJSFbean.showSelection}"/>
                                <h:commandButton value="state1" actionListener="#{stateBean.doState1}"/>
                        </h:form>
                        
                </body>
        </html>
</f:view>

下面是注册PhaseListener的那个bean的源代码
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/

package beans;

import javax.faces.FactoryFinder;
import javax.faces.event.ActionEvent;
import javax.faces.event.PhaseEvent;
import javax.faces.event.PhaseId;
import javax.faces.event.PhaseListener;
import javax.faces.lifecycle.Lifecycle;
import javax.faces.lifecycle.LifecycleFactory;

/**
*
* @author bache
*/

public class StateTestingBean {

        public StateTestingBean() {
                System.out.println("执行构造方法StateTestingBean()");
                Lifecycle lifecycle = ((LifecycleFactory) FactoryFinder.getFactory(FactoryFinder.LIFECYCLE_FACTORY)).getLifecycle(LifecycleFactory.DEFAULT_LIFECYCLE);
                lifecycle.addPhaseListener(new PhaseListener() {

                        public void beforePhase(PhaseEvent event) {
                                System.out.println("RESTORE_VIEW: beforePhase");
                        }

                        public void afterPhase(PhaseEvent event) {
                                System.out.println("RESTORE_VIEW: afterPhase");
                        }

                        public PhaseId getPhaseId() {
                                return PhaseId.RESTORE_VIEW;
                        }
                });
                lifecycle.addPhaseListener(new PhaseListener() {

                        public void beforePhase(PhaseEvent event) {
                                System.out.println("APPLY_REQUEST_VALUES: beforePhase");
                        }

                        public void afterPhase(PhaseEvent event) {
                                System.out.println("APPLY_REQUEST_VALUES: afterPhase");
                        }

                        public PhaseId getPhaseId() {
                                return PhaseId.APPLY_REQUEST_VALUES;
                        }
                });
                lifecycle.addPhaseListener(new PhaseListener() {

                        public void beforePhase(PhaseEvent event) {
                                System.out.println("PROCESS_VALIDATIONS: beforePhase");
                        }

                        public void afterPhase(PhaseEvent event) {
                                System.out.println("PROCESS_VALIDATIONS: afterPhase");
                        }

                        public PhaseId getPhaseId() {
                                return PhaseId.PROCESS_VALIDATIONS;
                        }
                });
                lifecycle.addPhaseListener(new PhaseListener() {

                        public void beforePhase(PhaseEvent event) {
                                System.out.println("UPDATE_MODEL_VALUES: beforePhase");
                        }

                        public void afterPhase(PhaseEvent event) {
                                System.out.println("UPDATE_MODEL_VALUES: afterPhase");
                        }

                        public PhaseId getPhaseId() {
                                return PhaseId.UPDATE_MODEL_VALUES;
                        }
                });
                lifecycle.addPhaseListener(new PhaseListener() {

                        public void beforePhase(PhaseEvent event) {
                                System.out.println("INVOKE_APPLICATION: beforePhase");
                        }

                        public void afterPhase(PhaseEvent event) {
                                System.out.println("INVOKE_APPLICATION: afterPhase");
                        }

                        public PhaseId getPhaseId() {
                                return PhaseId.INVOKE_APPLICATION;
                        }
                });
                lifecycle.addPhaseListener(new PhaseListener() {

                        public void beforePhase(PhaseEvent event) {
                                System.out.println("RENDER_RESPONSE: beforePhase");
                        }

                        public void afterPhase(PhaseEvent event) {
                                System.out.println("RENDER_RESPONSE: afterPhase");
                        }

                        public PhaseId getPhaseId() {
                                return PhaseId.RENDER_RESPONSE;
                        }
                });
        }

        public void doState1(ActionEvent e) {
        }
}