侧边栏壁纸
  • 累计撰写 59 篇文章
  • 累计创建 0 个标签
  • 累计收到 17 条评论

SpringBoot在Thread中注入Bean无效的解决方案

小熊博客
2021-12-31 / 0 评论 / 3 点赞 / 1,986 阅读 / 1,588 字
温馨提示:
本文最后更新于 2021-12-31,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

前言

当我们碰到复杂业务的时候可能需要开启新的线程处理,往往需要在线程中注入公共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();
    }
}
3

评论区