@Value 用於注入.properties文件中定義的內容
@Autowired 用於裝配bean
用法都很簡單,很直接,但是稍不注意就會出錯。下面就來說說我遇到的問題。
前兩天在項目中遇到了一個問題,大致描述就是我寫了如下一個類(只列出關鍵代碼):
@Component
@PropertySource("classpath:/config/config.properties")
public class MqttServiceClient implements IMqttServiceClient{
@Value("${mqtt_host}")
private String host;
@Value("${mqtt_client}")
private String client;
private MqttClient mqttClient;
public MqttService(){
mqttClient= new MqttClient(host,client, new MemoryPersistence());
}
}
並在其它類中定義了MqttServiceClient 類型的成員變量mqttServiceClient ,並用@Autowired注解進行注入,如下:
public class A{
@Autowired
private MqttServiceClient mqttServiceClient ;
...
}
然后運行時發現host和client總是為null,就是沒有注入。但是各個配置都是對的,在項目中的其它類用同樣的方法使用@Value注解時,就能夠取到值。
提示的報錯信息是MqttServiceClient 這個bean不能正確的創建。
一開始我以為是因為@Value注解沒有正確取值導致MqttServiceClient 類的構造函數不能正常運行從而導致的錯誤,所以沒在意提示的錯誤。
后來才發現,我所有的用法都沒錯,錯就錯在我重寫的構造函數上:
因為Java類會先執行構造方法,然后再給注解了@Value的成員變量注入值(@Autowired也一樣),所以在執行構造方法的時候,就會報錯。
我的解決辦法是,把@Value注解的屬性寫入一個AppConfig類中,然后在MqttServiceClient 中注入AppConfig類的對象,並用構造器注入,這樣可以明確成員變量的加載順序。
如下:
public class MqttServiceClient implements IMqttServiceClient{
private AppConfig appConfig;
private MqttClient mqttClient;
@Autowired
public MqttServiceClient(AppConfig appConfig){
this.appConfig = appConfig;
mqttClient = new MqttClient (appConfig.getHost(), appconfig.getClient, new MemoryPersistence()
}
}

