Jsf 2 FacesContext的生命周期?

Jsf 2 FacesContext的生命周期?,jsf-2,thread-safety,facescontext,Jsf 2,Thread Safety,Facescontext,当我翻阅课文时,我偶然发现了这句话 在调用其release()方法之前,该实例保持活动状态,之后不允许进一步引用该实例。当FacesContext实例处于活动状态时,除了执行此web应用程序的servlet容器用于处理此请求的线程外,不能从任何线程引用它 这是否意味着FacesContext永远不会进行垃圾收集,并且只有在当前Web应用程序停止(服务器停止)时才会销毁实例 FacesContext是否遵循单例模式?在这种情况下,当多个请求同时出现并呈现响应时,它将如何表现,因为它每次只服务一个请

当我翻阅课文时,我偶然发现了这句话

在调用其release()方法之前,该实例保持活动状态,之后不允许进一步引用该实例。当FacesContext实例处于活动状态时,除了执行此web应用程序的servlet容器用于处理此请求的线程外,不能从任何线程引用它

这是否意味着
FacesContext
永远不会进行垃圾收集,并且只有在当前Web应用程序停止(服务器停止)时才会销毁实例

FacesContext
是否遵循单例模式?在这种情况下,当多个请求同时出现并呈现响应时,它将如何表现,因为它每次只服务一个请求

这是否意味着
FacesContext
永远不会进行垃圾收集,并且只有在当前Web应用程序停止(服务器停止)时才会销毁实例

不,你看错了。
FacesContext
与单个HTTP请求一样有效。如果您在您自己的代码中的任何地方错误地引用了它(实际上,“can”是一个更好的词),它将不会立即被GC'ed。例如,作为会话范围的托管bean的一个属性,其寿命比单个HTTP请求长:

@ManagedBean
@SessionScoped
public class BadSessionBean {

    // Bad Example! Never do this! Not threadsafe and instance can't be GC'ed by end of request!
    private FacesContext context = FacesContext.getCurrentInstance();

}
如果您在代码中的任何地方都没有这样做,因此您总是在方法局部范围内获取当前实例,那么它将有机会被正确地GC’ed

@ManagedBean
@SessionScoped
public class GoodSessionBean {

    public void someMethod() {
        // OK! Declared in method local scope and thus threadsafe.
        FacesContext context = FacesContext.getCurrentInstance();
    }

}
请注意,这种GC行为并不特定于JSF/
FacesContext
,它只是一般特定于基本Java


FacesContext
是否遵循单例模式?在这种情况下,当多个请求同时出现并呈现响应时,它将如何表现,因为它每次只服务一个请求


不,绝对不是单身。它是一个实例,由
FacesServlet
service()
方法输入之后创建,并在
service()
方法离开之前由
FacesServlet
销毁。因此,每个请求(而不是每个应用程序)只有一个实例。请注意,一个HTTP请求算作一个单独的线程。可以有多个线程(读:请求),因此在应用程序的生命周期中可以有多个
FacesContext
实例。它的主要模式是,但这与它是
ThreadLocal
无关

另见:

请注意,一个HTTP请求算作一个单独的线程。可以有多个线程(读:请求),因此在应用程序的生命周期中可以有多个FacesContext实例..感谢您的深入..我一直在寻找这句话..:),所以在这种情况下,不建议在会话范围的bean中获取FacesContext实例?根据规则,FacesContext的实例不应在两个请求之间共享?不客气。在这种情况下,这个相关的答案可能也有助于更好地理解servlet在JSF的掩护下是如何工作的:不,你又看错了。不建议将其分配为会话范围bean的属性。您必须改为在方法局部范围中获取它。方法块中声明的任何变量都是threadlocal(因此是线程安全的)。我用另一个例子扩展了答案。好的..好的..那么一旦我们离开这个方法,它就会被销毁..因为没有引用。。