警告:无法注册销毁回调

时间:2010-01-16 14:14:19

标签: java spring jsf orchestra

  

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,我的类路径中没有弹簧jar(即不是类加载问题)

FacesRequestAttribute的文档说:

  

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

purchaseController实际上是一个简单的托管bean(不扩展任何只实现Serializable的内容),注释为@Controller

UPDATE1:

@Scope("request")@Scope("session")中的bean似乎受到了影响。 所以我想知道这个警告是否对正确的流动造成任何危险。即如果有什么东西真的需要那些回调。如果没有,我将跳过lo4j config的警告。

更新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容器实现中存在问题吗?

2 个答案:

答案 0 :(得分:11)

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

  

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

事实上,FacesRequestAttributesregisterDestructionCallback()方法并没有做太多事情:

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());
       }
   }
}

如果你看一下ServletRequestAttributes#requestCompleted()的javadoc:

  

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

所以,我认为你可以安全地跳过带有log4j配置的WARN(虽然可以用一点调试会话来确认)。

答案 1 :(得分:5)

我尝试添加

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

正如erhan14对此forum post所建议的那样。

那个警告对我来说消失了。希望它有所帮助。