SpringBoot 從application.yml中經過@Value讀取不到屬性值

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

相關文章
相關標籤/搜索