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的聲明週期的屬性形成的。java