我正在尝试在基于 Spring Boot 的 Java 应用程序中使用外部环境变量。
我已经声明了一个类来从应用程序中读取变量。属性文件:
@Component
@ConfigurationProperties(prefix = "etao")
public class ConfigurationData {
private String cronPrintDateTime = "";
private String searchEngineId = "";
private String googleApiKey = "";
public String getCronPrintDateTime() {
return this.cronPrintDateTime;
}
public void setCronPrintDateTime(String cronPrintDateTime) {
this.cronPrintDateTime = cronPrintDateTime;
}
public String getSearchEngineId() {
return this.searchEngineId;
}
public void setSearchEngineId (String searchEngineId) {
this.searchEngineId = searchEngineId;
}
public String getGoogleApiKey () {
return this.googleApiKey;
}
public void setGoogleApiKey (String gooogleApiKey) {
this.googleApiKey = gooogleApiKey;
}
}
只要我可以在应用程序的另一部分使用它来读出环境变量,就可以了:
@Component
public class ScheduledTasks {
@Autowired
private ConfigurationData configurationData;
@Scheduled(cron ="0 * * * * ?")
public void printDateTime() {
SimpleDateFormat sdf = new SimpleDateFormat(configurationData.getCronPrintDateTime());
sdf.setTimeZone(TimeZone.getTimeZone("Europe/Berlin"));
Date now = new Date();
String strDate = sdf.format(now);
System.out.println("Task executed at: " + strDate);
}
}
现在我尝试访问代码不同部分中的其他变量:
public class GoogleSearch {
@Autowired
private ConfigurationData configurationData;
private String CX_SEARCH_ENGINE_ID;
private String GOOGLE_API_KEY;
private Search searchResult;
// List<Result> searchResultItems;
public GoogleSearch() {
this.CX_SEARCH_ENGINE_ID = configurationData.getSearchEngineId();
this.GOOGLE_API_KEY = configurationData.getGoogleApiKey();
}
// Other code ...
}
这里失败了:
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'com.demo.views.search.SearchView': Failed to instantiate [com.demo.views.search.SearchView]: Constructor threw exception
Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.demo.views.search.SearchView]: Constructor threw exception
Caused by: java.lang.NullPointerException: Cannot invoke "com.demo.utils.ConfigurationData.getSearchEngineId()" because "this.configurationData" is null
所以是的,我的构造函数失败了,因为
configurationData
为空,所以自动接线不起作用,但我不知道为什么?
我是否需要以某种方式包装
ConfigurationData.class
才能生成它的多个实例/Bean?
如果有人感兴趣,我找到了一个有效的解决方案。基本上,我无法在多个地方自动装配 ConfigurationData 类,因此我构建了一个服务类并将 ConfigurationData 自动装配到服务类中:
@Service
public class ConfigurationDataService {
@Autowired
private ConfigurationData configurationData;
public String getCronPrintDateTime() {
return configurationData.getCronPrintDateTime();
}
public String getSearchEngineId() {
return configurationData.getSearchEngineId();
}
public String getGoogleApiKey () {
return configurationData.getGoogleApiKey();
}
}
之后,我不再直接在 ScheduledTasks 和 GoogleSearch 中使用 ConfigurationData,而是注入 ConfigurationDataService 类并使用它来获取我需要的环境变量。