I have a method with @PostConstruct annotation which uses autowired service
@Service
public ServiceWithPostConstruct{
private AutowiredService autowiredService;
@Autowired
public ServiceWithPostConstruct(AutowiredService autowiredService) {
this.autowiredService= autowiredService;
}
@PostConstruct
public void doSomething() {
autowiredService.doSomethingElse();
}
}
AutowiredService declaration
@Component
public class AutowiredService {
private static final Logger LOGGER = LoggerFactory.getLogger(AutowiredService .class);
private static final String SUCCESS_CODE = "0";
private RestOperations restOperations;
@Autowired
public AutowiredService (RestOperations restOperations) {
this.restOperations = restOperations;
}
///
}
somewhere else in the code, I have a completely unrelated component, which has a scope = request
@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class ScopedService{
}
and listener in web.xml
org.springframework.web.context.request.RequestContextListener
this service works correctly, where it is used.
However while starting the application, I get the following error:
12-Dec-2017 13:24:15.221 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class org.springframework.web.context.ContextLoaderListener org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'controller' defined in file [controller.class]: Unsatisfied dependency expressed through constructor parameter 1; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'serviceWithPostConstruct': Invocation of init method failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'scopedTarget.scopedService': 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.
This error might have been understood if I would be autowiring the mentioned ScopedService. But clearly I am not. I don't understand, why this @PostConstruct method has anything to do with ScopedService. If I remove the @PostConstruct annotation problem disappears. And the ScopedService works everywhere as intended, in Singletons as well. However, only if I get rid of the @PostConstruct annotation. Unfortunately, I need to keep it.
I am certain that the use of autowired service in doSomething() method is the core of the problem, if I remove the autowired service, the application starts correctly. It seems, that because of this @PostConstruct method, Spring checks ALL services, and when it comes to the ScopedService (the only component with scope=request) it recognizes that in that moment there is no HttpRequest and throws an error. Why? It is not connected in any way with that ScopedService.
What can be done about that? I will appreciate any ideas.