问题描述
多线程下,向数据库批量导入数据,出现空指针NullPointerException。
原因
使用多线程时,普通类无法直接调用服务层service,以及持久层类方法,如果直接调用service层方法以及持久层的方法会报空指针异常。因为所获得的对象并没有通过 @Autowired 注入进来。
解决办法
解决该问题有以下两种方法进行解决:
解决方案一:
1.定义一个spring工具配置类,用于调用spring ioc容器中的bean对象。创建代码如下:
@Component
public class SpringUtils implements ApplicationContextAware {
private static ApplicationContext applicationContext;
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
if ( null == SpringUtils.applicationContext){
SpringUtils.applicationContext = applicationContext;
}
}
//获得上下文
public static ApplicationContext getApplicationContext(){
return applicationContext;
}
//根据name获得bean
public static Object getBean(String name){
return getApplicationContext().getBean(name);
}
//根据class获得bean
public static <T> T getBean(Class<T> tClass){
return getApplicationContext().getBean(tClass);
}
//通过name.class获得bean
public static <T> T getBean(String name, Class<T> tClass){
return getApplicationContext().getBean(name,tClass);
}
}
2.在定义的普通类定义一个变量,用于存储获得的bean对象,并通过静态代码块获得我们想要的对象信息。
private static BatchSuperviseProductMapper batchSuperviseProductMapper;
static {
batchSuperviseProductMapper = SpringUtils.getBean(BatchSuperviseProductMapper.class);
}
如下如图所示:
解决方案2
1.保留通过注解获得对象
@Autowired
private static BatchSuperviseProductMapper batchSuperviseProductMapper;
2.定义一个操作持久层的函数
/*
*第二种:
* 1.保留通过@Authorid获取bean对象
* 2.修改run()方法中的代码,此处不进行调用持久层函数,改为调用外部方法,由外部方法调用持久层进行处理
* 3.外部定义一个函数用来处理插入数据
*
* */
public int sendMeg(List<Product> plist){
/*
*操作持久层代码
* */
}
3.在线程的run方法中调用该函数进行添加数据操作