use*_*676 2 java spring spring-mvc
Spring提供的作用域之一是request,其中的bean仅在请求的上下文中有效。
在 HTTP 请求之后,该请求通常会委托给控制器,并且 Spring 已经设置了所有必要的内容。
但是,如果请求来自不同的源(例如 Java 消息服务)怎么办?
是否可以为消息的每次处理设置一个请求范围?
我可以用一些东西注释一个方法以将其标记为请求范围的边界吗?
在幕后,Spring 只是在处理 HTTP 请求时在开始时调用RequestContextHolderset RequestAttributesto ,并在该线程处理完请求之前将其删除。请求和会话范围 bean 实际上存储在 this 中并从中获取。ThreadLocalThreadLocalRequestAttributes
在正常的 Web 情况下,此RequestAttributes实现由HttpServletRequest. 但是,在非 Web 环境中,没有HttpServletRequest,因此您不能使用现有的实现。其中一种方法是实现RequestAttributes由内部映射支持的 :
public class InMemoryRequestAttributes extends AbstractRequestAttributes {
protected Map<String, Object> attributes = new HashMap<>();
@Override
public Object getAttribute(String name, int scope) {
return attributes.get(name);
}
@Override
public void setAttribute(String name, Object value, int scope) {
attributes.put(name, value);
}
@Override
public void removeAttribute(String name, int scope) {
attributes.remove(name);
}
@Override
public String[] getAttributeNames(int scope) {
String[] result = new String[attributes.keySet().size()];
attributes.keySet().toArray(result);
return result;
}
@Override
public void registerDestructionCallback(String name, Runnable callback, int scope) {
synchronized (this.requestDestructionCallbacks) {
this.requestDestructionCallbacks.put(name, callback);
}
}
@Override
public Object resolveReference(String key) {
return attributes;
}
@Override
public String getSessionId() {
return null;
}
@Override
public Object getSessionMutex() {
return null;
}
@Override
protected void updateAccessedSessionAttributes() {
}
}
Run Code Online (Sandbox Code Playgroud)
注意:它仅适用于请求范围 bean。如果您也想支持会话范围 bean,请修改它......
然后设置它并从ThreadLocal之前删除它并完成 JMS 消息的处理,如下所示:
public void receive(String message){
RequestContextHolder.setRequestAttributes(new InMemoryRequestAttributes());
fooBean.processMessage(message);
RequestContextHolder.resetRequestAttributes();
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
15749 次 |
| 最近记录: |