2015-09-04 2 views
5

Mojarra 2.2.12Понимание FacesContext детали конкретизация

Вот фрагмент кода с более инстанциации 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" 

JavaDocs для FactoryFinder описывает так называемый

стандартный алгоритм открытия для всех заводских объектов, указанных в 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. Не могли бы вы объяснить этот цикл?

ответ

6

Существует специальный «init FacesContext», который доступен во время инициализации контейнера сервлета, гарантируя, что во время инициализации JSF существует не менее «a» FacesContext. Этот специальный «init FacesContext» имеет множество свойств empty/null/default, особенно те, которые зависят от запроса/ответа HTTP-сервлета, но свойства, связанные с приложением и конфигурацией, такие как доступные через FacesContext#getApplication(), уже доступны на основе a.o. faces-config.xml.

В случае Mojarra этот «init FacesContext» равен created в a.o. com.sun.faces.config.FacesInitializer, реализация ServletContainerInitializer, которая выполняется во время запуска webapp. В этот момент заводы создаются.

+0

Так вот, для создания InitFacesContext: 'FacesContextFactory privateFacesContextFactory = (FacesContextFactory) FactoryFinder.getFactory (" com.sun.faces.ServletContextFacesContextFactory ");'? Он не отображается в [Mojarra 2.2.4] (http://grepcode.com/file/repo1.maven.org/maven2/com.sun.faces/jsf-api/2.2.4/javax/faces/ context/FacesContext.java # FacesContext.getCurrentInstance% 28% 29) хотя ... –

+0

Нет, он создан в 'FacesInitializer'. Нажмите ссылку «Создать» в моем ответе. – BalusC

+0

Почему возникает ошибка JSF при попытке запустить приложение Spring на GF 4.1.1 без каких-либо ссылок на Mojarra: Info: WebModule [null] ServletContext.log(): Нет типов Spring WebApplicationInitializer, обнаруженных на пути к классам Info : Инициализация Mojarra 2.2.12 для контекста '/sm-shop-2.0.3-SNAPSHOT' Тяжелый: не удается получить InjectionProvider из времени init FacesContext. Этот контейнер реализует SPI Mojarra Injection SPI? Жесткий: невозможно вызвать аннотированные методы @PreDestroy, потому что не может быть найден Инъекционный инструмент. Этот контейнер реализует SPI Mojarra Injection SPI? – developer10