@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()
}
}