package cn.exrick.xboot.mqtt;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@Configuration
public
class PubService {
private static final Logger log = LoggerFactory.getLogger(PubService.class);
private MqttConfig mqttConfig;
private static MqttClient client;
// 在构造函数中注入mqttConfig能获取到mqttConfig从application.yml中获取到的值
public
PubService(@Autowired MqttConfig mqttConfig) {
this.mqttConfig = mqttConfig;
init();
}
// @Bean
// public
// PubService pubService() {
// return new PubService();
// }
private
void init() {
try {
client = new MqttClient(mqttConfig.host, mqttConfig.clientId, new MemoryPersistence());
// client = new MqttClient("tcp://106.14.181.253:1883", "SmartStreet", new MemoryPersistence());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(mqttConfig.userName);
connOpts.setPassword(mqttConfig.password.toCharArray());
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(20);
client.connect(connOpts);
client.setCallback(new PubServiceCallBack(client));
log.trace("Pub service client Connected");
} catch (MqttException e) {
log.error("build Pub service failed " + e.getMessage());
}
}
public
void publishTop() {
MqttMessage message = new MqttMessage();
message.setQos(2);
message.setRetained(true);
message.setPayload("{\"CHx\":\"ON\"}".getBytes());
try {
client.publish("Pub/80001001/CHx", message);
} catch (MqttException e) {
e.printStackTrace();
}
}
public static
void publishTop(String topic, MqttMessage msg) throws MqttException {
try {
client.publish(topic, msg);
} catch (MqttException e) {
log.error("public topic fail: Topic Name:\t" + topic + "fail message: " + e.getMessage());
e.printStackTrace();
throw e;
}
}
}
package cn.exrick.xboot.mqtt;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
@Configuration
public
class MqttConfig {
@Value("${ssmqtt.host}")
public String host;
@Value("${ssmqtt.server.name}")
public String userName;
@Value("${ssmqtt.server.password}")
public String password;
@Value("${ssmqtt.clientId}")
public String clientId;
}
package cn.exrick.xboot.mqtt;
import org.eclipse.paho.client.mqttv3.*;
import org.eclipse.paho.client.mqttv3.persist.MemoryPersistence;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
@Configuration
public
class PubService {
private static final Logger log = LoggerFactory.getLogger(PubService.class);
// 这种情况下,构造函数调用init方法就不能取到mqttConfig的值
@Autowired
private MqttConfig mqttConfig;
private static MqttClient client;
public
PubService() {
this.mqttConfig = mqttConfig;
init();
}
// @Bean
// public
// PubService pubService() {
// return new PubService();
// }
private
void init() {
try {
client = new MqttClient(mqttConfig.host, mqttConfig.clientId, new MemoryPersistence());
// client = new MqttClient("tcp://106.14.181.253:1883", "SmartStreet", new MemoryPersistence());
MqttConnectOptions connOpts = new MqttConnectOptions();
connOpts.setCleanSession(true);
connOpts.setUserName(mqttConfig.userName);
connOpts.setPassword(mqttConfig.password.toCharArray());
connOpts.setConnectionTimeout(10);
connOpts.setKeepAliveInterval(20);
client.connect(connOpts);
client.setCallback(new PubServiceCallBack(client));
log.trace("Pub service client Connected");
} catch (MqttException e) {
log.error("build Pub service failed " + e.getMessage());
}
}
public
void publishTop() {
MqttMessage message = new MqttMessage();
message.setQos(2);
message.setRetained(true);
message.setPayload("{\"CHx\":\"ON\"}".getBytes());
try {
client.publish("Pub/80001001/CHx", message);
} catch (MqttException e) {
e.printStackTrace();
}
}
public static
void publishTop(String topic, MqttMessage msg) throws MqttException {
try {
client.publish(topic, msg);
} catch (MqttException e) {
log.error("public topic fail: Topic Name:\t" + topic + "fail message: " + e.getMessage());
e.printStackTrace();
throw e;
}
}
}
主要问题的原因就是,构造函数的执行顺序先于类属性的赋值。在构造函数中使用属性的值且从application.yml通过@Value获取,此时Spring容器还没有向属性赋值。这是Spring Bean的声明周期的属性造成的。