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