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

相关文章
相关标签/搜索