javaspringautowiredobject-poolingrequestscope

Spring - Request scoped bean from object pool


I have an object pool of resources:

public interface PooledResource {
   ...
}

@Component
public class ResourcePool {
    public PooledResource take()                              { ... }
    public void           give(final PooledResource resource) { ... }
}

Currently, I am using this pool as following in my JAX-RS endpoints:

@Path("test")
public class TestController {
    @Autowired
    private ResourcePool pool;

    @GET
    Response get() {
        final PooledResource resource = pool.take();
        try {
            ...
        }
        finally {
            pool.give(resource);
        }
    }

}

This works fine. However, requesting the PooledResource manually and being forced to not forget the finally clause makes me nervous. I would like to implement the controller as following:

@Path("test")
public class TestController {
    @Autowired
    private PooledResource resource;

    @GET
    Response get() {
        ...
    }

}

Here, the PooledResource is injected, instead of the managing pool. This injection should be request scoped, and also, after finalization of the request, the resource must be given back to the pool. This is important, or we will run out of resources eventually.

Is this possible in Spring? I have been playing with FactoryBean, but this does not seem to support to give back the bean.


Solution

  • Implement a HandlerInterceptor and inject it with a request scoped bean. When preHandle is called, setup the bean with the correct value. When afterCompletion is called, clean it up again.

    Note that you will need to combine this with a Bean Factory to get a nice PooledResource injection into your other components.

    The Factory basically injects the same object as you used in the HandlerInterceptor and creates (or just returns) a PooledResource.