我有一个Sping Boot 项目,在其中我实现了责任链模式。我创建了多个服务类的链。每个服务的范围都是Singleton。现在我有2个线程正在访问单例bean,然后在这种情况下,一个线程所做的修改会影响其他线程在同一个bean上工作。我尝试将bean范围作为请求,但它不起作用。
TransactionChainContext -定义链
@Service
public class TransactionChainContext {
@Autowired
TransactionChain validationChainOne;
@Autowired
TransactionChain validationChainTwo;
@Autowired
TransactionChain validationChainThree;
@Autowired
TransactionChain validationChainFour;
@Autowired
TransactionChain validationChainFive;
/* Execute by Thread 1 */
public void saveTransactionInChain() {
validationChainOne.nextChain(validationChainTwo);
validationChainTwo.nextChain(validationChainThree);
validationChainThree.nextChain(validationChainFour);
validationChainFour.nextChain(null);
validationChainOne.processChain();
}
/* Execute by Thread 2 but it changes the chaing for thread 1 as well */
public void saveChainTwo() {
validationChainOne.nextChain(validationChainFour);
validationChainFour.nextChain(validationChainFive);
validationChainFive.nextChain(null);
validationChainOne.processChain();
}
}
TransactionChain接口
public interface TransactionChain {
void nextChain(TransactionChain transactionChain);
void processChain();
}
验证类
@Service
public class ValidationChainOne implements TransactionChain {
TransactionChain nextTransactionChain;
@Override
public void nextChain(TransactionChain transactionChain) {
this.nextTransactionChain = transactionChain;
}
@Override
public void processChain() {
// some business logic
}
}
"我所尝试的"
为了确保两个线程不会相互影响,我将bean范围作为request
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
但出现以下错误
'scopedTarget.ValidationChainOne': 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: In this case, use RequestContextListener or RequestContextFilter to expose the current request.
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:368)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:202)
at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:673)
1条答案
按热度按时间xxb16uws1#
就我个人而言,我会从
TransactionChain
中删除nextChain(...)
方法,这样它是不可变的,因此是线程安全的。我个人讨厌
@Autowired
和@AfterPropertiesSet
,而且从来没有使用过它们。我更喜欢最终成员变量和构造函数注入。