В Spring легко автоматически подключать bean-компоненты и делать их доступными в любом месте в контексте приложения. Компоненты могут быть специализированы для такой области, как сеанс / запрос / веб-сокет и т. д.
У меня довольно уникальный сценарий. Я получаю сообщение от брокера сообщений, что означает, что запрос не получен в «Контроллере». Из-за этого Spring не создает bean-компонентов @RequestScope (вся эта логика в Spring основана на использовании аннотаций @Controller / @RequestMapping / обработчика DispatchServlet).
Есть ли способ создать bean-компонент в области запроса с помощью Spring AutowireCapableBeanFactory или каким-либо другим способом?
Я хочу сделать что-то вроде приведенного ниже, в котором SomeService.handle сможет получить доступ к методу getName() в RequestScopeBean. В настоящее время генерируется это исключение.
Исключение:
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
Код
@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);
}
}
Вау, позволь мне попробовать это, понятия не имею, почему это не пришло мне в голову
это не сработало, вероятно, потому, что нет @RequestMapping
Ответ на этот вопрос может помочь: stackoverflow.com/questions/15415688/…
Нет, ты не можешь. Поскольку прицелы request и session привязаны к сети (и не связаны с @Controller, здесь важна сеть). Во входящем сообщении нет веб-понятия для, так что это не сработает.
Очевидно, вам нужно ограничить его контекстом, в котором вы его используете. @Controller сам по себе просто имеет область действия всего приложения
@ m-deinum Мне определенно пришлось создать другую область видимости, чтобы справиться с этим
тогда почему бы не попробовать @Prototype?




Почему бы не аннотировать свой клиент брокера сообщений с помощью @Controller и таким образом получить доступ к контексту? Я не понимаю, в чем причина того, что я этого не делаю.