了解 FacesContext 实例化细节
Understanding FacesContext instantiation details
Mojarra 2.2.12
这是接管 FacesContext 实例化的代码片段:
FacesContext context = facesContextFactory.getFacesContext
(servletConfig.getServletContext(), request, response, lifecycle);
表达的很清楚。一旦我们收到请求,我们就会从中获取全局信息并使用它创建 FacesContext
实例。因此,实例是为每个请求创建的。但是获得 facesContextFactory
的实例在我看来要棘手得多。
// Acquire our FacesContextFactory instance
try {
facesContextFactory = (FacesContextFactory)
FactoryFinder.getFactory
(FactoryFinder.FACES_CONTEXT_FACTORY);
} catch (FacesException e) {
//others
}
哪里
String javax.faces.FactoryFinder.FACES_CONTEXT_FACTORY = "javax.faces.context.FacesContextFactory"
FactoryFinder
的 JavaDocs 描述了所谓的
standard discovery algorithm for all factory objects specified in the
JavaServer Faces APIs.
这就是我困惑的地方。
现在,让我们考虑创建工厂实例的实际方法:javax.faces.FactoryFinderInstance#getFactory(String factoryName)
try {
factoryOrList = factories.get(factoryName);
if (!(factoryOrList instanceof List)) {
return factoryOrList;
}
} finally {
lock.readLock().unlock();
}
factories
字段初始化如下copyInjectionProviderFromFacesContext():
private void copyInjectionProviderFromFacesContext() {
InjectionProvider injectionProvider = null;
FacesContext context = FacesContext.getCurrentInstance(); //USE FACES CONTEXT!!!!!
if (null != context) {
injectionProvider = (InjectionProvider) context.getAttributes().get("com.sun.faces.config.ConfigManager_INJECTION_PROVIDER_TASK");
}
if (null != injectionProvider) {
factories.put(INJECTION_PROVIDER_KEY, injectionProvider);
} else {
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, "Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI?");
}
}
}
因此,创建使用 FacesContext
实例,但工厂本身用于创建 FacesContext
。你不能解释一下那个周期吗?
有一个特殊的“init FacesContext”,它在 servlet 容器初始化期间可用,确保在 JSF 初始化期间至少有 "a" FacesContext
。这个特殊的 "init FacesContext" 有很多 empty/null/default 属性,尤其是那些依赖于 HTTP servlet request/response 的属性,但是应用程序和配置相关的属性,例如通过 FacesContext#getApplication()
可用的属性已经可用基于 a.o。 faces-config.xml
.
对于 Mojarra,此 "init FacesContext" 是在 webapp 启动期间运行的 created in a.o. the com.sun.faces.config.FacesInitializer
, a ServletContainerInitializer
实现。在那一刻,工厂被创建。
Mojarra 2.2.12
这是接管 FacesContext 实例化的代码片段:
FacesContext context = facesContextFactory.getFacesContext
(servletConfig.getServletContext(), request, response, lifecycle);
表达的很清楚。一旦我们收到请求,我们就会从中获取全局信息并使用它创建 FacesContext
实例。因此,实例是为每个请求创建的。但是获得 facesContextFactory
的实例在我看来要棘手得多。
// Acquire our FacesContextFactory instance
try {
facesContextFactory = (FacesContextFactory)
FactoryFinder.getFactory
(FactoryFinder.FACES_CONTEXT_FACTORY);
} catch (FacesException e) {
//others
}
哪里
String javax.faces.FactoryFinder.FACES_CONTEXT_FACTORY = "javax.faces.context.FacesContextFactory"
FactoryFinder
的 JavaDocs 描述了所谓的
standard discovery algorithm for all factory objects specified in the JavaServer Faces APIs.
这就是我困惑的地方。
现在,让我们考虑创建工厂实例的实际方法:javax.faces.FactoryFinderInstance#getFactory(String factoryName)
try {
factoryOrList = factories.get(factoryName);
if (!(factoryOrList instanceof List)) {
return factoryOrList;
}
} finally {
lock.readLock().unlock();
}
factories
字段初始化如下copyInjectionProviderFromFacesContext():
private void copyInjectionProviderFromFacesContext() {
InjectionProvider injectionProvider = null;
FacesContext context = FacesContext.getCurrentInstance(); //USE FACES CONTEXT!!!!!
if (null != context) {
injectionProvider = (InjectionProvider) context.getAttributes().get("com.sun.faces.config.ConfigManager_INJECTION_PROVIDER_TASK");
}
if (null != injectionProvider) {
factories.put(INJECTION_PROVIDER_KEY, injectionProvider);
} else {
if (LOGGER.isLoggable(Level.SEVERE)) {
LOGGER.log(Level.SEVERE, "Unable to obtain InjectionProvider from init time FacesContext. Does this container implement the Mojarra Injection SPI?");
}
}
}
因此,创建使用 FacesContext
实例,但工厂本身用于创建 FacesContext
。你不能解释一下那个周期吗?
有一个特殊的“init FacesContext”,它在 servlet 容器初始化期间可用,确保在 JSF 初始化期间至少有 "a" FacesContext
。这个特殊的 "init FacesContext" 有很多 empty/null/default 属性,尤其是那些依赖于 HTTP servlet request/response 的属性,但是应用程序和配置相关的属性,例如通过 FacesContext#getApplication()
可用的属性已经可用基于 a.o。 faces-config.xml
.
对于 Mojarra,此 "init FacesContext" 是在 webapp 启动期间运行的 created in a.o. the com.sun.faces.config.FacesInitializer
, a ServletContainerInitializer
实现。在那一刻,工厂被创建。