Understanding FacesContext instantiation details

谁都会走 提交于 2019-12-10 14:59:32

问题


Mojarra 2.2.12

Here is the piece of code taking over the instantiation of the FacesContext:

FacesContext context = facesContextFactory.getFacesContext
              (servletConfig.getServletContext(), request, response, lifecycle);

The expression is perfectly clear. Once we get a request, we acquire a global information from it and create the FacesContext instance using it. So, the instance is created for each request. But obtaining the intance of facesContextFactory seemed to me much more tricky.

// Acquire our FacesContextFactory instance
try {
    facesContextFactory = (FacesContextFactory)
        FactoryFinder.getFactory
        (FactoryFinder.FACES_CONTEXT_FACTORY);
} catch (FacesException e) {
    //others
}

Where

String javax.faces.FactoryFinder.FACES_CONTEXT_FACTORY = "javax.faces.context.FacesContextFactory"

JavaDocs for the FactoryFinder describes the so called

standard discovery algorithm for all factory objects specified in the JavaServer Faces APIs.

This is what I was confused by.

Now, Let's consider the the actual method that creates the factory instance: javax.faces.FactoryFinderInstance#getFactory(String factoryName)

try {
      factoryOrList = factories.get(factoryName);
      if (!(factoryOrList instanceof List)) {
          return factoryOrList;
      }
} finally {
      lock.readLock().unlock();
}

The factories field is initialized as follows 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?");
        }
    }
}

So, creating used FacesContext instance, but the factory itself is used for creating the FacesContext. Couldn't you explain that cycle?


回答1:


There's a special "init FacesContext" which is available during servlet container initialization, ensuring that there's at least "a" FacesContext around during JSF initialization. This special "init FacesContext" has a lot of empty/null/default properties, particularly the ones depending on HTTP servlet request/response, but application and configuration related properties such as ones available via FacesContext#getApplication() are already available based on a.o. faces-config.xml.

In case of Mojarra, this "init FacesContext" is created in a.o. the com.sun.faces.config.FacesInitializer, a ServletContainerInitializer implementation which runs during webapp startup. During that moment, factories are created.



来源:https://stackoverflow.com/questions/32391917/understanding-facescontext-instantiation-details

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!