Spring 对多线程的支持

最近的项目中有个问题是处理从 ERP 上传商品到电商慢的问题,之前的操作是 ERP 先上传对应的商品的图片到电商服务器,然后上传商品信息到电商数据库,这样存在一个问题,ERP 上传图片到电商服务器速度很慢,因为要跨外网,改进的做法是,ERP 先将商品信息上传到电商数据库,商品信息中包含有图片的绝对路径,图片的处理交由电商这边去上传,返回图片上传的地址,写到对应的表,这里想到的是用多线程去处理图片上传,好了,开始干活。

在商品信息保存完成后,开启一个线程

ImageThread imageThread = new ImageThread(commonId);
imageThread.start();

ImageThread 线程类继承 Thread,重写 run 方法,在 run 方法里面处理图片上传和写相关数据信息,在 ImageThread 类里面使用注解 @Autowired 注入了很多 Dao,因为这里要查数据和写数据,写完相关逻辑后,开始愉快的跑起来。

打开 Postman 开始调用接口,好嘞,商品上传完成,返回 commonId,多线程进入到 ImageThread 类里面,调试发现注入的 Dao 全为 null,以为是配置文件没开启注解扫描,类没写 @Component 注解等错误,都检查了一遍,发现没错,回过头来看了下开线程的方法,开启线程使用了 new,可是项目是使用 spring 来管理对象的啊,这里竟然用了 new 来创建对象,GG,如果用 new 创建对象那还要 spring 干什么用。于是开始搜索 spring 多线程处理,原来 spring 对多线程的支持很简单,直接贴代码吧。

定义配置类:

@Configuration  
@ComponentScan("common.util")  
@EnableAsync
public class ThreadConfig {
    @Bean  
    public Executor getExecutor() {  
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();  
         executor.setCorePoolSize(5);  
         executor.setMaxPoolSize(10);  
         executor.setQueueCapacity(25);  
         executor.initialize();  
         return executor;  
    }  
}

写要执行的任务:

    @Async
    public void run(int commonId) {
      //省略逻辑处理部分
    }

直接调用:

  imageThread.run(commonId);

完成。

出现这个为空的问题还是因为自己对 spring 的对象管理理解不够透彻,使用 spring 注解注入取不到值主要有以下几种情况:

  1. 注解扫描没有扫描到对应的包
  2. 类上没有加上相应的注解,例如:@Component,@Service,@Controller
  3. 使用了 new 创建对象