前言
Spring Boot使用线程的run方法中调用service报java.lang.NullPointerException
提示:以下是本篇文章正文内容,下面案例可供参考
壹:场景
多线程的情况下run方法体中调用业务层的方法。
贰:原因
多数情况下Spring框架中使用IOC容器中的bean
事先它会初始化好,接下来我们再加以引用对吧。你会用这两个注解@Autowired、@Resource
。
但是如果在线程类中要用SpringIOC容器中的bean你用前面的两个注解是不起作用的,因为你的线程类不被Spring管理,在线程中为了线程安全,是防注入的
。你品你细品是不是这个样子,这时候你想注入建立关系那是不可能的。
那怎么办呢?项目都已经启动了,这时候是不是还有一种办法
可以拿到SpringIOC容器中的bean那就是从我们的上下文ApplicationContext
中,没错就是它。
叁:方法
取类实现ApplicationContextAware接口,编写获取bean的方法即可。
package com.jhkj.td.config;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;
@Component
public class GetBeanUtil implements ApplicationContextAware {
private static ApplicationContext applicationContext;
public void setApplicationContext(ApplicationContext context) {
GetBeanUtil.applicationContext = context;
}
public static Object getBean(String name) {
return applicationContext.getBean(name);
}
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
}
肆:实现
package com.jhkj.td.config;
import com.alibaba.fastjson.JSONObject;
import com.jhkj.td.model.ReverseResult;
import com.jhkj.td.model.TireRealTimeData;
import com.jhkj.td.service.Impl.TireRealTimeDataServiceImpl;
import com.jhkj.td.service.TireRealTimeDataService;
import com.jhkj.td.utils.ConvertUtil;
import com.jhkj.td.utils.DateUtils;
import com.jhkj.td.utils.MapUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.math.BigDecimal;
import java.math.RoundingMode;
import java.net.Socket;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.util.Date;
import static com.jhkj.td.config.SocketHandler.*;
@Slf4j
@Data
public class ClientSocket implements Runnable {
private Socket socket;
private DataInputStream inputStream;
private DataOutputStream outputStream;
private String key;
private String message;
@Override
public void run() {
while (true) {
try {
SocketHandler.onMessage(this);
TireRealTimeDataService tireRealTimeDataService = (TireRealTimeDataService) GetBeanUtil.getBean("tireRealTimeDataService");
TireRealTimeData realTimeData = new TireRealTimeData();
String msg = this.message.trim().substring(2, this.message.length() - 2);
log.info("本地时间 ---> {}", LocalDateTime.now());
log.info("接收到数据 ---> {}", message);
log.info("数据解析 --> 去除标识符后的数据---{}", msg);
String msgId = msg.substring(0, 4);//消息ID WORD 命名规则:平台0x8XXX;终端0x0XXX;
realTimeData.setMsgId(ConvertUtil.hexToDecimal(msgId));
String checkCode = msg.substring(112, 114);//检验码
realTimeData.setCheckCode(ConvertUtil.hexToDecimal(checkCode));
tireRealTimeDataService.saveOrUpdate(realTimeData);
} catch (Exception e) {
e.printStackTrace();
}
if (isSocketClosed(this)) {
log.info("客户端已关闭,其Key值为:{}", this.getKey());
//关闭对应的服务端资源
close(this);
break;
}
}
}
}
提示 |
---|
本人以抱着学习的态度去分享,以上内容如有雷同,不胜荣幸!如有不足,欢迎评论留言! |