Java 请求范围的bean不会调用@PreDestroy方法

Java 请求范围的bean不会调用@PreDestroy方法,java,spring,Java,Spring,我已经创建了一个请求范围的bean,它应该在请求结束后调用一个方法。 我试图用@PreDestroy注释的方法来实现,但这不起作用 @Component @Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS) public class SessionProvider { @PreDestroy public void cleanup() { // DO STUFF } } 如

我已经创建了一个请求范围的bean,它应该在请求结束后调用一个方法。 我试图用@PreDestroy注释的方法来实现,但这不起作用

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class SessionProvider {
    @PreDestroy
    public void cleanup() {
        // DO STUFF
    }
}

如何实现所描述的行为?

我通过注册自己的RequestContextListener解决了这个问题:

public class MyRequestContextListener
        extends RequestContextListener {

    @Override
    public void requestDestroyed( ServletRequestEvent requestEvent ) {

        super.requestDestroyed( requestEvent );
        applicationContext.getBean( SessionProvider.class ).cleanup();
    }
}
希望这能帮助其他人


最好的问候,Chris

如果您使用过滤器或拦截器,您可以避免编写自定义请求上下文侦听器,而是将请求范围的bean插入过滤器中,并在其中进行清理

例如,在使用jersey的rest应用程序中,我们以以下方式释放应用程序中的资源-

public class MyResourceManager implements ContainerResponseFilter {

    /* MyCustomIO class is defined to be request 
    scoped using proxyMode = TARGET_CLASS */
    @Inject  // Use @Autowired if you aren't using JSR-330 annotations
    private MyCustomIO myIO;

    @Override
    public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException {
        // Perform your clean up here
        myIO.cleanup();
    }

}
有些人可能会争辩说,过滤器并不是用于此目的的,但我们意识到,有时过滤器是在“请求”级别进行资源清理的最佳场所——这是因为通常我们的目标是在请求完成时(或在请求完成之前)释放请求期间占用的资源。依赖bean上的destroy方法回调可能不一定会在请求完成时释放资源,因为我们无法控制垃圾收集

另外,由于过滤器执行后发生的唯一主要事情是响应对象序列化,它不需要任何IO,因此此时清理资源是相当安全的,而不必担心它们仍在使用。
但当然,此解决方案不能用于在会话或应用程序级别进行清理。

您可以在此处发布spring xml文件的代码片段吗?PreDestroy是在销毁此组件的实例之前调用的,它没有任何请求。你可以向这个类中添加方法来处理你的请求,或者请解释你所说的“请求结束”是什么意思@john我想他会在请求完成后立即检查预结构是否工作,因为他将其范围限定为“请求”预结构-在创建对象之前调用一个方法;)@Christoph-看看这个:(OP从来没有让它工作过,但也许你的情况类似)。实现
DisposableBean
Closeable
,而不是使用注释。