Need Proxy?

BotProxy: Rotating Proxies Made for professionals. Really fast connection. Built-in IP rotation. Fresh IPs every day.

Find out more


How to inject a scoped-proxy bean into a singleton bean by using constructor injection

Question

I'm developing a web application using Spring MVC, and want to have a request scoped Date bean which indicates when each request happens. To define such Date bean, I have written a following bean definition into application context xml.

<bean id="now"
      class="java.util.Date"
      scope="request">
    <aop:scoped-proxy/>
</bean>

Injecting this bean into a singleton bean by using field injection works fine.

public class ASingletonBean {
    @Autowired
    private Date now;
    ...
}

But I don't want to use field injection because it's not recommended. My IDE suggests to use constructor injection instead.

public class ASingletonBean{
    private final Date now;

    @Autowired
    public ASingletonBean(Date now) {
        this.now = now;
    }
}

Now the code above throws a following exception when the application launches.

org.springframework.beans.factory.BeanCreationException:
Error creating bean with name 'scopedTarget.java.util.Date#0':
Scope 'request' is not active for the current thread;
consider defining a scoped proxy for this bean if you intend to refer to it from a singleton;
nested exception is java.lang.IllegalStateException:
No thread-bound request found: Are you referring to request attributes outside of an actual web request, or processing a request outside of the originally receiving thread?
If you are actually operating within a web request and still receive this message, your code is probably running outside of DispatcherServlet/DispatcherPortlet:
In this case, use RequestContextListener or RequestContextFilter to expose the current request.

How can I avoid this error?

Answer

Please, don't do that. Creating a new bean (you don't need) on every request is an overhead that can be easily avoided. Instead create a class + bean that implements java.util.function.Supplier for example:

@Component
class DateTimeProvider implements java.util.function.Supplier<Date> {
...
}

and then inject this java.util.function.Supplier<Date> into your `ASingletonBean'. This way, you will be able to get a current date/time when processing a request.

And few additional notes:

  • Use JodaTime or JDK8 JavaTime API instead of java.util.Date,
  • If you cannot use JDK8 (java.util.function.Supplier was added in JDK8) then you can either create your own interface or use one provided by Guava,
  • If you need a very precise timing for the received request then you should consider creating some sort of a "time stamping" filter, most likely by extending org.springframework.web.filter.OncePerRequestFilter class.

Edited - to answer a questions from comment:

  • "why it is preferable to using request-scoped bean" - A bean would always have to be injected to any business component you would create. Seems a bit much for just having a 'request timestamp'.

  • The request object you receive from the outside world should be translated into some sort of a 'domain request' (that contains the timestamp) and then handled internally only in its domain form. (read more on: Hexagonal Architecture a.k.a Ports and Adapters, Domain Driver Design). Why so? Because one can easily imagine that a request that now enters the system only by the means of HTTP request could enter the system in the form of JMS message or batch import operation - then you would only need to provide a new adapter to the system and entire logic inside core domain would not change.

  • If you are using Spring Boot then it is enough to create a bean that extends org.springframework.web.filter.OncePerRequestFilter#OncePerRequestFilter and implement your logic inside the only method that needs to be implemented. Spring will automatically use your filter.

cc by-sa 3.0