在浏览 javadoc of FacesContext
时,我遇到了这句话
这是否意味着 FacesContext
永远不会进行垃圾回收,并且只有在当前 web 应用程序停止(服务器停止)时才会销毁实例?FacesContext
是否遵循单例模式?在这种情况下,当多个请求同时来渲染响应时,它会如何表现,因为它每次只服务一个请求?
最佳答案
不,你读错了。 FacesContext
的生命周期与单个 HTTP 请求一样长。如果您在您自己的代码之外的任何地方错误地引用了它(实际上,“可以”是一个更好的词),则不会立即对其进行GC处理。例如。作为 session 范围托管 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 处理。@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。不,它绝对不是单例。它是一个
ThreadLocal
实例,在进入 FacesServlet
方法之后立即由 service()
创建并在离开 FacesServlet
方法之前由 service()
销毁。因此,每个请求 只有一个实例 (因此不是每个应用程序)。请注意,一个 HTTP 请求算作一个单独的线程。可以有多个线程(读取:请求),因此在应用程序的生命周期内可以有多个 FacesContext
实例。它的主要模式是 facade pattern ,但这与它是 ThreadLocal
无关。也可以看看: