这是否意味着FacesContext
永远不会进行垃圾收集,并且只有在当前 web 应用程序停止(服务器停止)时才会销毁实例?
不,你读错了。与FacesContext
单个 HTTP 请求一样长。如果您在自己的代码中超出其范围的任何地方错误地引用它,它将(实际上,“可以”是一个更好的词)不会立即被 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
遵循单例模式吗?在这种情况下,当多个请求同时呈现响应时它会如何表现,因为它每次只服务一个请求?
不,这绝对不是单例。它是一个ThreadLocal
实例,在方法进入FacesServlet
后由右边创建,在方法离开前由右边销毁。因此,每个请求只有一个实例(因此不是每个应用程序)。请注意,一个 HTTP 请求算作一个单独的线程。可以有多个线程(读取:请求),因此在应用程序的生命周期中可以有多个实例。它的主要模式是外观模式,但这与它是无关的。service()
FacesServlet
service()
FacesContext
ThreadLocal
也可以看看: