警告:无法注册销毁回调

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

这条警告消息在我的日志中出现了很多 。 对于每个托管bean到期时。 它会在一段时间后过期,因为我正在使用MyFaces Orchestra。

我在我的web.xml定义了org.springframework.web.context.request.RequestContextListener ,我的classpath中没有spring jar(即不是类加载问题)

FacesRequestAttribute的文档说:

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

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

UPDATE1:

@Scope("request")@Scope("session")的bean似乎受到影响。 所以我想知道这个警告是否对正确的流动造成任何危险。 即如果真的需要那些回调。 如果没有,我将跳过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容器实现中的问题?

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 ServletRequestAttributes#requestCompleted()

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

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

我尝试添加

  org.springframework.web.context.request.RequestContextListener  

正如erhan14在此论坛post中所建议的那样。

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