前言
当我们在多线程或监听器中使用@Autowired注入对象时,会发现报 java.lang.NullPointerException 空指针异常
提示:以下是本篇文章正文内容,下面案例可供参考
一、问题
多线程中使用@Autowired注入UserService时,userService使用时为null,获取不到bean;
主要原因:new thread不在spring容器中,也就无法获得spring中的bean对象,需要手动获取。
@Autowired
private UserService userService;
二、示例代码
1.问题复现
以下为简单代码分析:在controller中调用多线程,多线程中调用 userService
- controller中调用多线程
@PostMapping("/demoThread")
public void demoThread(){
DemoThread demoThread = new DemoThread();
new Thread(demoThread).start();
}
- 实现runnable,重写run方法,run方法中调用userService
public class DemoThread implements Runnable {
@Autowired
private UserService userService;
@Override
public void run() {
List<UserEntity> list = userService.list();
System.out.println(list);
}
}
- 运行结果
2.解决办法
手动获取bean对象
public class DemoThread implements Runnable {
// 使用AppContextUtils.getBean(UserService.class);获取bean对象
private UserService userService = AppContextUtils.getBean(UserService.class);
@Override
public void run() {
List<UserEntity> list = userService.list();
System.out.println(list);
}
}
AppContextUtils
@Component
public class AppContextUtils implements ApplicationContextAware {
private static ApplicationContext appContext;
@Override
public void setApplicationContext(@NonNull ApplicationContext applicationContext) throws BeansException {
appContext = applicationContext;
}
public static <T> T getBean(Class<T> requiredType) {
return appContext.getBean(requiredType);
}
public static <T> T getBean(String name, Class<T> requiredType) {
return appContext.getBean(name, requiredType);
}
public static String getId() {
return appContext.getId();
}
}
总结
不要说看破红尘心已寒,红尘本就是清浊合流浪滔天;不要说怀才不遇,才华本就是为人作嫁铺路砖。