0

In Spring it's easy to autowire beans and have them available anywhere in the app context. Beans can be specialized to a scope such as session/request/web socket etc.

I have a rather unique scenario. I receive a message from a message broker which means the request is not received in a "Controller". Because of this, Spring is not creating @RequestScope beans (All of this logic in Spring is based on using the @Controller/@RequestMapping annotations / DispatchServlet handler). Is there a way to create a bean within the request scope with the Spring AutowireCapableBeanFactory or some other way?

I want to do something like the below in which the SomeService.handle will be able to access the getName() method of the RequestScopeBean. Currently it throws this exception.

Exception:

BeanCreationException: Error creating bean with name ' 
scopedTarget.getRequestUtils': Scope 'request' is not active for the 
current thread; consider defining a scoped proxy for this bean

Code

@Service
public class MyMessagingReceiver implements SomeMessageReceiver {

    private final SomeService someService;

    @Autowired
    public MyMessagingReceiver(final SomeService someService) {
        this.someService = someService;
    }

    public void onMessage(MessageObject messageObject) {
        //possible here to use AutowireCapableBeanFactory in inject the RequestScopeBean bean?
        someService.handle(messageObject);
    }
}

@Service
public class SomeService {

    private final RequestScopeBean requestScopeBean;

    @Autowired
    public SomeService(RequestScopeBean requestScopeBean) {
        this.requestScopeBean = requestScopeBean;
    }

    public void handle(MessageObject messageObject) {
        System.out.println(this.requestScopeBean.getName());
    }

}

@Configuration
public class BeanDeclarations {
    @Bean
    @RequestScope
    public RequestScopeBean requestScopeBean() {
        return new RequestScopeBean();
    }
}

public RequestScopeBean {
    private String name;

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }
}

public class Interceptor extends HandlerInterceptorAdapter {
    private RequestScopeBean requestScopeBean;

    @Autowired
    public Interceptor(RequestScopeBean requestScopeBean) {
        this.requestScopeBean = requestScopeBean;
    }

    @Override
    public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler) throws Exception {
        String name = request.getHeader("name");
        this.requestScopeBean.setName(name);
    }


} 
8
  • Why not annotate your message broker client with @Controller and get access to the context that way? I'm unclear what the reason is for opting not to do that. Commented Nov 19, 2018 at 23:32
  • Wow, let me actually try that, no idea why this didn't occur to me Commented Nov 20, 2018 at 2:58
  • that did not work, probably because there is no @RequestMapping Commented Nov 20, 2018 at 3:32
  • The answer to this one might help: stackoverflow.com/questions/15415688/… Commented Nov 20, 2018 at 5:13
  • 1
    No you cannot. As request and session scopes are tied to the web (and not related to @Controller it is the web that is important here). There is no web notion for in incoming message so no that will not work. Commented Nov 20, 2018 at 9:18

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.