若直接在Thread子类中通过注解方式注入Bean是无效的
原因:因为Spring本身默认Bean为单例模式构建,同时是非线程安全的,因此禁止了在Thread子类中的注入行为,因此在Thread中直接注入的bean是null的,会发生空指针错误。
如下面的代码,需要注入ItemMapper,有如下两种解决方案
方案1 :将需要的Bean作为线程的的构造函数的参数传入
import cn.haiwang.mapper.ItemMapper;
import cn.haiwang.service.Task_B;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.*;
@RestController
public class ChanpinController_1 {
@Autowired
private ItemMapper itemMapper;
@RequestMapping("/addChanpin_1")
public String addChanpin_1() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
// 通过构造函数引入
Task_B taskB = new Task_B(itemMapper);
Future<Integer> future = executorService.submit(taskB);
Integer i = future.get();
return i>0? "添加成功": "添加失败";
}
}
import cn.haiwang.domain.Item;
import cn.haiwang.mapper.ItemMapper;
import java.time.LocalDateTime;
import java.util.concurrent.Callable;
//重点看这个类
public class Task_B implements Callable<Integer> {
private ItemMapper itemMapper;
// 通过构造函数引入
public Task_B(ItemMapper itemMapper) {
this.itemMapper = itemMapper;
}
@Override
public Integer call() throws Exception {
Item item = new Item(null, "电视1", "电视1", LocalDateTime.now());
return itemMapper.insert(item);
}
}
方案2:推荐方案!!!将线程类作为服务类的内部类,可以方便直接使用外部类中注入的bean
import cn.haiwang.domain.Item;
import cn.haiwang.mapper.ItemMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.time.LocalDateTime;
import java.util.concurrent.*;
@RestController
public class ChanpinController_2 {
@Autowired
private ItemMapper itemMapper;
@RequestMapping("/addChanpin_2")
public String addChanpin_2() throws ExecutionException, InterruptedException {
ExecutorService executorService = Executors.newFixedThreadPool(3);
Future<Integer> submit = executorService.submit(new Task_A());
Integer integer = submit.get();
return integer>0? "添加成功": "添加失败";
}
/**
* 内部类
*/
private class Task_A implements Callable<Integer> {
@Override
public Integer call() throws Exception {
Item item = new Item(null, "电视2", "电视2", LocalDateTime.now());
return itemMapper.insert(item);
}
}
}