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描述了所谓的
标准发现算法,用于指定的所有工厂对象 JavaServer Faces API。
这让我很困惑。
现在,让我们考虑创建工厂实例的实际方法: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
。你不能解释那个循环吗?
答案 0 :(得分:7)
在servlet容器初始化期间有一个特殊的“init FacesContext”,确保在JSF初始化期间至少有一个“FacesContext
。这个特殊的“init FacesContext”有很多空/ null /默认属性,特别是那些依赖于HTTP servlet请求/响应的属性,但是应用程序和配置相关的属性(例如通过FacesContext#getApplication()
可用的属性)已经基于a.o可用。 faces-config.xml
。
对于Mojarra,这个“init FacesContext”在a.o中是created。 com.sun.faces.config.FacesInitializer
,在webapp启动期间运行的ServletContainerInitializer
实现。在那一刻,工厂被创造出来。