如何在 Spring Boot 中使 ThreadPoolTask​​Executor 访问请求范围的 bean

时间:2021-03-17 10:31:09

标签: java spring spring-boot

我有要单独处理的项目列表。所以,我想使用 Java 并行流,但线程无法访问我的请求范围 bean。

我尝试了以下实现:

 @Bean(name = "myExecutor")
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);
        executor.setMaxPoolSize(10);
        executor.setQueueCapacity(25);
        executor.setThreadNamePrefix("my-thread");
        return executor;
    }

在我的服务层,我自动装配了执行器:

@Autowired
ThreadPoolTaskExecutor taskExecutor;
public void addOrUpdate(List<ShareholderBalanceCsvItem> itemList) {
        
        // ...

        itemList.forEach(csvItem -> taskExecutor.submit(() -> {
            log.info(Thread.currentThread().getName() + " ----------------------");
            
           // ...
           createCertificateShareEntry(processType, csvItem, certificateShareEntryDTO);
           // ...

        }));
}

我看到为列表中的 4 个项目正确生成了 4 个线程enter image description here

createCertificateShareEntry 方法中,我需要访问请求范围内的 MessageBean

@Autowired
private MessageBean messageBean;

private void createCertificateShareEntry(String processType, ShareholderBalanceCsvItem csvItem, CertificateShareEntryDTO certificateShareEntryDTO) {

        // ...
            certificateShareEntryDTO.setMessageOid(messageBean.getObjId());
        // ...
}

MessageBean.java

@Component
@Scope(value = "request", proxyMode = ScopedProxyMode.TARGET_CLASS)
public class MessageBean {
 // ...
} 

我在行 messageBean.getObjId()

中得到以下异常
Error creating bean with name 'scopedTarget.messageBean': 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: Cannot ask for request attribute - request is not active anymore!
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:383)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208)
    at org.springframework.aop.target.SimpleBeanTargetSource.getTarget(SimpleBeanTargetSource.java:35)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:675)
    at tr.com.mkk.hpks.model.MessageBean$$EnhancerBySpringCGLIB$$1db10d79.getObjId(<generated>)
    at tr.com.mkk.hpks.service.impl.ShareholderBalanceServiceImpl.createCertificateShareEntry(ShareholderBalanceServiceImpl.java:400)
    at tr.com.mkk.hpks.service.impl.ShareholderBalanceServiceImpl.lambda$addOrUpdate$4(ShareholderBalanceServiceImpl.java:314)
    at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:515)
    at java.base/java.util.concurrent.FutureTask.run$$$capture(FutureTask.java:264)
    at java.base/java.util.concurrent.FutureTask.run(FutureTask.java)
    at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
    at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
    at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: java.lang.IllegalStateException: Cannot ask for request attribute - request is not active anymore!
    at org.springframework.web.context.request.ServletRequestAttributes.getAttribute(ServletRequestAttributes.java:149)
    at org.springframework.web.context.request.AbstractRequestAttributesScope.get(AbstractRequestAttributesScope.java:43)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:371)
    ... 12 common frames omitted

0 个答案:

没有答案