11

15:11:14,676 WARN FacesRequestAttributes:121 - 无法为属性“purchaseController”注册销毁回调 [org.springframework.beans.factory.support.DisposableBeanAdapter@1059fd6],因为 FacesRequestAttributes 不支持此类回调

这个警告信息经常出现在我的日志。对于每个过期的托管 bean。它会在给定时间后过期,因为我使用的是 MyFaces Orchestra。

我已经org.springframework.web.context.request.RequestContextListener在我的 中定义了web.xml,并且我的类路径中没有弹簧罐(即不是类加载问题)

FacesRequestAttribute 的文档说:

注意:与 ServletRequestAttributes 相比,此变体不支持作用域属性的销毁回调,既不支持请求范围,也不支持会话范围。如果您依赖此类隐式销毁回调,请考虑在 web.xml 中定义 Spring RequestContextListener。

purchaseController实际上是一个简单的托管 bean(不扩展任何实现只)Serializable,用@Controller.

更新1:

@Scope("request")里面的豆子@Scope("session")似乎受到了影响。所以我想知道这个警告是否会对正确的流程造成任何危险。即,如果确实需要这些回调。如果没有,我将跳过带有 lo4j 配置的警告。

更新 2:

我进一步挖掘,似乎这种情况只是偶尔发生。如果使用了侦听器,则RequestContextHolder.currentRequestAttributes()返回ServletRequestAttributes,而不是FacesRequestAttributes。所以看起来有时监听器不起作用并且没有在RequestContextHolder.

更新 3:

我打开了调试RequestContextListener,结果如下:

07:21:31,518 DEBUG RequestContextListener:69 - Bound request context to thread: org.apache.catalina.connector.RequestFacade@1190ae9
07:21:31,518 DEBUG RequestContextListener:89 - Cleared thread-bound request context: org.apache.catalina.connector.RequestFacade@1190ae9
07:21:31,538  WARN FacesRequestAttributes:121 - Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@11aa152] for attribute 'org.apache.myfaces.orchestra.conversation.AccessScopeManager' because FacesRequestAttributes does not support such callbacks
07:21:31,541  WARN FacesRequestAttributes:121 - Could not register destruction callback [org.springframework.beans.factory.support.DisposableBeanAdapter@1552393] for attribute 'localeController' because FacesRequestAttributes does not support such callbacks
....and so on, other request and session beans

在尝试访问 bean 之前,请求似乎被破坏了。这很奇怪。这可能是由于侦听器处理的 servlet 容器实现中的问题吗?

4

2 回答 2

11

在 的 javadoc 中FacesRequestAttributes,我们可以阅读:

注意:与 相比ServletRequestAttributes,此变体不支持作用域属性的销毁回调,既不支持请求范围,也不支持会话范围。如果您依赖此类隐式销毁回调,请考虑RequestContextListener在 web.xml 中定义 Spring。

而且,确实,registerDestructionCallback()方法FacesRequestAttributes并没有做很多事情:

public void registerDestructionCallback(String name, Runnable callback, int scope) {
    if (logger.isWarnEnabled()) {
        logger.warn("Could not register destruction callback [" + callback + "] for attribute '" + name +
                        "' because FacesRequestAttributes does not support such callbacks");
    }
}

但我的理解是RequestContextListener(您已声明的)将负责这项工作。其requestDestroyed(ServletRequestEvent requestEvent) 方法如下图所示:

public void requestDestroyed(ServletRequestEvent requestEvent) {
   ServletRequestAttributes attributes =
           (ServletRequestAttributes) requestEvent.getServletRequest().getAttribute(REQUEST_ATTRIBUTES_ATTRIBUTE);
   ServletRequestAttributes threadAttributes =
           (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
   if (threadAttributes != null) {
       // We're assumably within the original request thread...
       if (attributes == null) {
           attributes = threadAttributes;
       }
       RequestContextHolder.resetRequestAttributes();
       LocaleContextHolder.resetLocaleContext();
   }
   if (attributes != null) {
       attributes.requestCompleted();
       if (logger.isDebugEnabled()) {
           logger.debug("Cleared thread-bound request context: " + requestEvent.getServletRequest());
       }
   }
}

如果您查看以下的 javadoc ServletRequestAttributes#requestCompleted()

执行所有请求销毁回调并更新在请求处理期间已访问的会话属性。

因此,我认为您可以使用 log4j 配置安全地跳过 WARN(尽管可以通过一些调试会话来确认这一点)。

于 2010-01-16T21:26:35.753 回答
5

我尝试添加

<listener>
    <listener-class>org.springframework.web.context.request.RequestContextListener</listener-class>
</listener>

正如 erhan14 在此论坛帖子上所建议的那样。

这个警告对我来说消失了。希望能帮助到你。

于 2012-12-30T02:46:23.960 回答