java – 异步服务中的Spring请求范围?在threadLocal变量上实现ThreadScope,并使用AsyncAspect进行清理
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了java – 异步服务中的Spring请求范围?在threadLocal变量上实现ThreadScope,并使用AsyncAspect进行清理,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含4261字,纯文字阅读大概需要7分钟。
内容图文
![java – 异步服务中的Spring请求范围?在threadLocal变量上实现ThreadScope,并使用AsyncAspect进行清理](/upload/InfoBanner/zyjiaocheng/816/fc613ec7e9674e55b4802b948242cf98.jpg)
我有一个启动一系列操作的Web服务.从同一请求开始的所有这些操作都共享一个包含一些锁和一些其他信息的actionContext.
到目前为止,Spring会在使用“请求”范围的所有操作中注入此actionContext对象.
现在我正在实现一个Web套接字服务,以便能够跟踪这些操作的演变.
webService现在必须生成一个处理动作执行的线程,并将webSocket地址返回给调用的应用程序/用户.
该操作已使用spring的@async注释实现,并将在应用程序上下文中定义的线程池中运行.
问题:
使用这个新功能,’request’范围不再起作用,因为生成的线程不是请求(Spring将阻止执行).
处理这个问题的最佳解决方案是什么?
>实现我的Thread范围来处理actionContext并在所有操作中正确注入它?
>手动传递actionContext(在我看来它看起来不太好)
>实现一个实例化webSocket的webService,并请求调用者首先调用它,然后将其引用传递给真正的webService?
谢谢您的帮助!
解决方法:
我决定尽可能保持干净,然后去实施TreadScope!
我的解决方案由:
> ThreadScope用于在同一个线程中运行的所有操作中注入相同的bean.
>拦截所有@async调用的方面asyncAspect,asyncAspectAfter()将去清理threadLocal变量.这是由@async注释方法的弹簧处理所要求的:因为Spring在池中运行方法,所以线程被重用而不会被破坏.这意味着threadLocal变量将在线程中持久存在.
ThreadScope
/**
* This scope works in conjunction with the {@link AsyncAspect} that goes to
* cleanup the threadScoped beans after an async run. This is required since in
* spring the async methods run in a pool of thread, so they could share some
* thread scoped beans.
*
*
* @author enrico.agnoli
*/
public class ThreadScope implements Scope {
/**
* This map contains for each bean name or ID the created object. The
* objects are created with a spring object factory. The map is ThreadLocal,
* so the bean are defined only in the current thread!
*/
private final ThreadLocal<Map<String, Object>> threadLocalObjectMap = new ThreadLocal<Map<String, Object>>() {
@Override
protected Map<String, Object> initialValue() {
return new HashMap<String, Object>();
};
};
/** {@inheritDoc} */
public Object get(final String beanName,
final ObjectFactory<?> theObjectFactory) {
Object object = threadLocalObjectMap.get().get(beanName);
if (null == object) {
object = theObjectFactory.getObject();
threadLocalObjectMap.get().put(beanName, object);
}
return object;
}
/** {@inheritDoc} */
public String getConversationId() {
// In this case, it returns the thread name.
return Thread.currentThread().getName();
}
/** {@inheritDoc} */
public void registerDestructionCallback(final String beanName,
final Runnable theCallback) {
// nothing to do ... this is optional and not required
}
/** {@inheritDoc} */
public Object remove(final String beanName) {
return threadLocalObjectMap.get().remove(beanName);
}
@Override
public Object resolveContextualObject(String key) {
// TODO Auto-generated method stub
return null;
}
/**
* Invoke this method to cleanUp the ThreadLocal beans. This call is
* required since in case of run in a thread pool, the thread will never be
* removed and the threadLocal variables would be shared between two
* different executions!
*/
public void cleanUpThreadScopedBeans() {
threadLocalObjectMap.remove();
}
}
AsyncAspect
/**
* This Async Aspect is used to cleanup the threadScoped beans after an async
* run. This is required since in spring the async methods run in a pool of
* thread, so they could share some thread scoped beans.<br>
* The Thread scope is defined in {@link ThreadScope}
*
* @author enrico.agnoli
*
*/
public class AsyncAspect {
@Autowired
ThreadScope threadScope;
private static final Logger log = LoggerFactory
.getLogger(AsyncAspect.class);
public void asyncAspectAfter() {
log.debug("CleanUp of the ThreadScoped beans");
threadScope.cleanUpThreadScopedBeans();
}
}
的ApplicationContext
<!-- Here we define the Thread scope, a bean exists only inside the same thread -->
<bean id="ThreadScope" class="com.myCompany.myApp.ThreadScope" />
<bean class="org.springframework.beans.factory.config.CustomScopeConfigurer">
<property name="scopes">
<map>
<entry key="thread">
<ref bean="ThreadScope"/>
</entry>
</map>
</property>
</bean>
<!-- Here we configure the aspect -->
<bean id="AsyncAspect" class="com.myCompany.myApp.AsyncAspect" />
<aop:config proxy-target-class="true">
<aop:aspect ref="AsyncAspect">
<aop:pointcut expression="@annotation(org.springframework.scheduling.annotation.Async)" id="asyncAspectId" />
<aop:after pointcut-ref="asyncAspectId" method="asyncAspectAfter" />
</aop:aspect>
</aop:config>
内容总结
以上是互联网集市为您收集整理的java – 异步服务中的Spring请求范围?在threadLocal变量上实现ThreadScope,并使用AsyncAspect进行清理全部内容,希望文章能够帮你解决java – 异步服务中的Spring请求范围?在threadLocal变量上实现ThreadScope,并使用AsyncAspect进行清理所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。