线程 run 方法中调用 service 报 java.lang.NullPointerException

线程 run 方法中调用 service 报 java.lang.NullPointerException

前言

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;
            }
        }
    }
}

Alt
在这里插入图片描述

提示
本人以抱着学习的态度去分享,以上内容如有雷同,不胜荣幸!如有不足,欢迎评论留言!
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值