前言
当我们碰到复杂业务的时候可能需要开启新的线程处理,往往需要在线程中注入公共bean,大家可能第一时间想到的是@Autowired注解注入。
比如:
/**
* @author: 小熊
* @date: 2021/12/31 11:40
*/
@Component
public class demoThread extends Thread {
@Autowired
private WxUserService wxUserService;
@Override
public void run() {
wxUserService.getUserInfoByOpenId("123456");
super.run();
}
}
如果你这样做了,那么恭喜你,你会发现注入失败了。那这个时候你往往会问了?为什么会注入失败呢?原因嘛,其实很简单,因为Spring本身默认Bean是单例构建的,并且是线程不安全的,所以Spring禁止了在Thread的子类中的注入行为,所以会注入失败并且引发空指针错误。
如何解决呢?跟着我往下看。
方案一.在非Thread类中注入bean提供给Thread调用
/**
* 注入bean
*/
@Component
public class FC {
public static WxUserService wxUserService;
@Autowired
public void setBean(WxUserService wxUserService) {
FC.wxUserService = wxUserService;
}
}
/**
* @author: 小熊
* @date: 2021/12/31 11:40
*/
public class demoThread extends Thread {
@Override
public void run() {
//调用bean
FC.wxUserService.getOpenId("123456");
}
}
方案二.用构造函数传入bean
/**
* @author: 小熊
* @date: 2021/12/31 11:40
*/
public class DemoThread extends Thread {
private WxUserService wxUserService;
//构造方法传入bean
public DemoThread(WxUserService wxUserService) {
this.wxUserService = wxUserService;
}
@Override
public void run() {
//调用bean
wxUserService.getOpenId("123456");
}
}
/**
* @author: 小熊
* @date: 2021/12/31 12:02
*/
@Service
@RequiredArgsConstructor
public class DomeService {
final WxUserService wxUserService;
public void test(){
//构造方法传入bean
Thread thread=new DemoThread(wxUserService);
thread.start();
}
}
方案三.将线程类作为服务类的内部类
/**
* @author: 小熊
* @date: 2021/12/31 12:02
*/
@Service
@RequiredArgsConstructor
public class DomeService {
final WxUserService wxUserService;
public void test() {
Thread thread = new Thread() {
@Override
public void run() {
//内部类直接调用
wxUserService.getUserInfoByOpenId("123456");
}
};
thread.start();
}
}
评论区