【问题标题】:Understanding FacesContext instantiation details了解 FacesContext 实例化细节
【发布时间】:2015-09-04 06:58:34
【问题描述】:

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

【问题讨论】:

    标签: jsf lifecycle


    【解决方案1】:

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

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

    【讨论】:

    • 那么,创建 InitFacesContext 就是这种情况:FacesContextFactory privateFacesContextFactory = (FacesContextFactory) FactoryFinder.getFactory("com.sun.faces.ServletContextFacesContextFactory");?虽然它没有出现在Mojarra 2.2.4...
    • 不,它是在FacesInitializer 中创建的。单击我的答案中的“已创建”链接。
    • 在没有任何 Mojarra 引用的情况下尝试在 GF 4.1.1 上运行 Spring 应用程序时出现 JSF 相关错误:信息:WebModule[null] ServletContext.log():No Spring WebApplicationInitializer在类路径信息中检测到的类型:为上下文“/sm-shop-2.0.3-SNAPSHOT”初始化 Mojarra 2.2.12 严重:无法从初始化时间 FacesContext 获取 InjectionProvider。这个容器是否实现了 Mojarra 注入 SPI?严重:无法调用 @PreDestroy 注释的方法,因为找不到 InjectionProvider。这个容器是否实现了 Mojarra Injection SPI?
    • @developer10:因为 GF 是 Java EE 服务器。 IE。它实现了来自 Java EE API 的任何东西,包括 JSF。通常,Spring 应用程序部署到非 Java EE 服务器,例如 Tomcat。另见 a.o. stackoverflow.com/questions/7295096/what-exactly-is-java-ee
    • @developer10:当然是在项目本身中。你不应该接触服务器的库。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多