了解FacesContext实例化详细信息

时间:2015-09-04 06:58:34

标签: jsf lifecycle

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。你不能解释那个循环吗?

1 个答案:

答案 0 :(得分:7)

在servlet容器初始化期间有一个特殊的“init FacesContext”,确保在JSF初始化期间至少有一个“FacesContext。这个特殊的“init FacesContext”有很多空/ null /默认属性,特别是那些依赖于HTTP servlet请求/响应的属性,但是应用程序和配置相关的属性(例如通过FacesContext#getApplication()可用的属性)已经基于a.o可用。 faces-config.xml

对于Mojarra,这个“init FacesContext”在a.o中是createdcom.sun.faces.config.FacesInitializer,在webapp启动期间运行的ServletContainerInitializer实现。在那一刻,工厂被创造出来。