问小白 wenxiaobai
资讯
历史
科技
环境与自然
成长
游戏
财经
文学与艺术
美食
健康
家居
文化
情感
汽车
三农
军事
旅行
运动
教育
生活
星座命理

实现Runnable接口,自定义实现类传参问题

创作时间:
作者:
@小白创作中心

实现Runnable接口,自定义实现类传参问题

引用
CSDN
1.
https://m.blog.csdn.net/weixin_42752467/article/details/144865777

在使用Spring框架和线程池时,如何正确传递参数到Runnable实现类是一个常见的问题。本文通过一个具体的错误案例,详细解释了为什么需要无参构造器,并提供了两种解决方案。

在学习使用线程池(ThreadPoolTaskExecutor)开启多线程的过程中,发现自定义实现类实现Runnable接口,使用有参构造器进行参数的传递,出现如下报错:

Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'executorTestImpl' defined in file [******************************]: Unsatisfied dependency expressed through constructor parameter 0; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'java.util.concurrent.atomic.AtomicInteger' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {}

源代码如下:

@Component
public class ThreadPoolExcecutorTask {
    @Resource(name = "threadPoolTaskExecutor")
    ThreadPoolTaskExecutor taskExecutor;
    public void executorTest() {
        AtomicInteger count = new AtomicInteger();
        for ( int i = 0; i < 100; i++) {
            count.set(i);
            taskExecutor.execute(new ExecutorTestImpl(count));
        }
    }
}
@Component
public class ExecutorTestImpl implements Runnable {
    private AtomicInteger count;
    @Override
    public void run() {
        System.out.println(Thread.currentThread().getName()+"::"+ count);
    }
    public ExecutorTestImpl(AtomicInteger count) {
        this.count = count;
    }
}  

其实此时,IDEA以已经给了提示,实现类的有参构造器count下面有红色波浪线标注。

后面查了查资料,有两套解决方案:

1、在配置中显式地定义一个
AtomicInteger
的bean。也最麻烦

@Configuration
public class AppConfig {
    @Bean
![](https://wy-static.wenxiaobai.com/chat-rag-image/13573648681920063750)
    public AtomicInteger atomicInteger() {
        return new AtomicInteger();
    }
}

2、加一上无参构造器

@Component
public class ExecutorTestImpl implements Runnable {
    private AtomicInteger count;
    
    @Override
    public void run() {
        
        System.out.println(Thread.currentThread().getName()+"::"+ count);
    }
    public ExecutorTestImpl(AtomicInteger count) {
        this.count = count;
    }
    public ExecutorTestImpl() {}
    
}

至于为什么,度娘给的解释是:

当实体类(Entity Class)被标记为@Component时,Spring 框架会尝试将其作为组件进行管理,并创建其实例。如果实体类没有无参数构造器,Spring 将无法创建它的实例,因为 Spring 需要通过调用无参数构造器来创建对象。同时,如果实体类有带参数的构造器,并且参数不是由 Spring 管理的bean,那么在创建实体类对象时也会出现问题,因为 Spring 无法通过构造器注入依赖。

目前能力有限,具体原理以后再慢慢探知。。

© 2023 北京元石科技有限公司 ◎ 京公网安备 11010802042949号