BotProxy: Rotating Proxies Made for professionals. Really fast connection. Built-in IP rotation. Fresh IPs every day.
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?
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:
java.util.function.Supplier
was added in JDK8) then you can either create your own interface or use one provided by Guava,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.