参考:
https://gblfy.blog.csdn.net/article/details/94294855?utm_term=service%E6%97%A0%E6%B3%95%E6%B3%A8%E5%85%A5Component%E7%B1%BB&utm_medium=distribute.pc_aggpage_search_result.none-task-blog-2allsobaiduweb~default-1-94294855&spm=3001.4430
package cn.org.emcs.emergencynews.framework.mqtt.cancel;
import cn.org.emcs.emergencynews.service.ECancelimformationService;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONException;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttCallback;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.annotation.PostConstruct;
@Slf4j
@Component//关键点 1 为spring组件
public class CancelCallback implements MqttCallback {
//添加所需eCancelimformationService的私有成员
@Autowired
ECancelimformationService eCancelimformationService;
// 关键点2 静态初使化 这样是为了在spring初使化之前
private static CancelCallback cancelCallback;
//关键 3 通过@PostConstruct 和 @PreDestroy 方法 实现初始化和销毁bean之前进行的操作
@PostConstruct
public void init() {
cancelCallback = this;
// 初使化时将已静态化的configParam实例化
cancelCallback.eCancelimformationService = this.eCancelimformationService;
}
@Override
public void connectionLost(Throwable throwable) {
//连接丢失后,一般在这里面进行重连
log.info("断开了MQTT连接 :{}", throwable.getMessage());
log.error(throwable.getMessage(), throwable);
}
//客户端回调
@Override
public void messageArrived(String topic, MqttMessage mqttMessage) throws Exception {
try{
// subscribe后得到的消息会执行到这里面
log.info("收到来自Cancel: " + topic + " 的消息:{}", new String(mqttMessage.getPayload()));
//此处可能因为收到的消息不合法,会造成JSON转化异常,若异常未捕获,会导致MQTT客户端掉线
JSONObject jsonObject = JSON.parseObject(new String(mqttMessage.getPayload()));
String str = jsonObject.toJSONString();
/*------------将得到的消息存入数据库中,并推送出去------------*/
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
log.info("currentThread().getName======"+Thread.currentThread().getName());
//关键点 4 调用时请使用 此类静态变量 .对象 例如//cancelCallback.eCancelimformationService
cancelCallback.eCancelimformationService.pushCancelEarthquake(cancelCallback.eCancelimformationService,str);
}
});
thread.start();
}catch (JSONException e){
log.error("JSON Format Parsing Exception : {}", new String(mqttMessage.getPayload()));
}
/*-------------------------------------------*/
}
//服务端回调
@Override
public void deliveryComplete(IMqttDeliveryToken iMqttDeliveryToken) {
log.info("deliveryComplete---------" );
}
}
原因:可能是spring注入component时,service的类还为空,这时自动注入就失效了;
@Component, @Service, @Controller, @Repository是spring注解,注解后可以被spring框架所扫描并注入到spring容器来进行管理
@Component是通用注解,其他三个注解是这个注解的拓展,并且具有了特定的功能
@Repository注解在持久层中,具有将数据库操作抛出的原生异常翻译转化为spring的持久层异常的功能。
@Controller层是spring-mvc的注解,具有将请求进行转发,重定向的功能。
@Service层是业务逻辑层注解,这个注解只是标注该类处于业务逻辑层。
用这些注解对应用进行分层之后,就能将请求处理,义务逻辑处理,数据库操作处理分离出来,为代码解耦,也方便了以后项目的维护和开发。