[英]How to dynamically choose the configurations based on the environment in JAVA?
我有一個實用程序類,它具有與電子郵件發件人相關的常見配置,配置會根據環境(如Staging
和Production
更改。 現在我如何根據環境動態選擇配置?
這是我的代碼,
EmailUtility.java
package com.housecar.common;
public class EmailUtility {
//For staging
public static final String FROM_EMAIL_ID = "xx12@xyz.com";
public static final String FROM_NAME = "xyz";
static final String SMTP_USERNAME = "xx12@xyz.com";
static final String SMTP_PASSWORD = "15sss67$";
public static final String REPLY_EMAIL_ID = "xx12@xyz.com";
public static final String MAIL_SMTP_PORT = "587";
public static final String MAIL_SMTP_SOCKET_FACTORY_PORT = "587";
public static final String SMTP_HOST = "smtp.gmail.com";
public static final String MAIL_SMTP_SOCKETFACTORY_CLASS = "javax.net.ssl.SSLSocketFactory";
//for production
/*public static final String FROM_EMAIL_ID = "admin@xyz.com";
public static final String FROM_NAME = "xyz";
static final String SMTP_USERNAME = "AKYeeeELEQAGAA"; // Replace with
// your SMTP
// username.
static final String SMTP_PASSWORD = "gvwwwwwbgpGm/C/LmUYUK5HosQar7mTSwjl5MFeBRR";
public static final String REPLY_EMAIL_ID = "admin@xyz.com";
public static final String MAIL_SMTP_PORT = "587";
public static final String MAIL_SMTP_SOCKET_FACTORY_PORT = "587";
public static final String SMTP_HOST = "email-smtp.us-east-1.amazonaws.com";
public static final String MAIL_SMTP_SOCKETFACTORY_CLASS = "javax.net.ssl.SSLSocketFactory";*/
}
在我的代碼中,我手動注釋掉配置!
您應該從屬性存儲中查找系統依賴值(例如,由Javas Properties
類處理的屬性文件)。
但是您不應該在同一個文件中提供所有系統信息。
您應該具有單獨的文件(具有相同的名稱),並使您的部署過程將目標系統的文件復制到預期的位置。
這樣,您就可以讓操作團隊使用您(作為開發人員)不應該知道的數據來操作(或預配置)屬性文件,例如。 高安全系統的密碼......
將以下內容添加到application.properties
文件中:
from.email.id = xx12@xyz.com
from.name = xyz
...
等等
您可以在啟動應用程序之前定義這些屬性(具體取決於您的情況)。 當然,您需要將它們注入到您的類中,如下所示:
@Value("${from.email.id}")
private String fromEmailId;
所以現在fromEmailId
將賦值給application.properties
文件。
祝好運。
編輯:
如果你想安全的一點點更高的水平,你可以使用jasypt
到CRIPT您的密碼到您的applicaiton.properties
文件。 最后,密碼看起來像這樣:
smtp.password = ENC(5KZL2q+Ute21FzCsJy/h0aIp75TZgHBHx8L11R+jTJs0=)
您可以使用屬性文件來解決您的問題,例如,根據環境,您可以擁有兩個屬性文件。
1)config_staging.properties 2)config_production.properties
並將您的臨時電子郵件配置移動到config_staging.properties,將您的生產配置移動到config_production.properties。
這將在運行應用程序時配置。
例如,
config_staging.properties
smtp.username = "xx12@xyz.com";
smtp.password = "15sss67$";
config_production.properties
smtp.username = "AKYeeeELEQAGAA";
smtp.password = "gvwwwwwbgpGm/C/LmUYUK5HosQar7mTSwjl5MFeBRR";
然后將它們注入到EmailUtility類中,
@Value("${smtp.username}")
private String smtpUsername;
@Value("${smtp.password}")
private String smtpPassword;
否則,如果您需要在運行應用程序時更改配置並且正在使用數據庫,則可以使用鍵值配置在數據庫中創建配置表,並在代碼中讀取它們。
例如,像這樣的表:
CREATE TABLE configuration (
key varchar(255),
value varchar(255)
);
其中key
是屬性名稱, value
是屬性值。
一個屬性
environment=development
可能成為
INSERT INTO configuration (key, value) VALUES('environment', 'development');
這里的其他答案是朝着正確方向邁出的一步。
有人建議將配置值移動到.properties
文件中。 這是朝着正確方向邁出的一大步,但忽略了你正在使用Spring Boot的事實。
有人建議將配置值移動到Spring application.properties
或application.yaml
文件中。 這是Spring應用程序的更好選擇。 application.properties
實際上只是一個像第一個建議的.properties
文件,但是由Spring Framework自動加載。 這在第24章 “ Spring Boot參考指南的 外部化配置”中有所描述。
但是,你的問題實際上說:
[...]與電子郵件發件人相關的常見配置 ,配置根據環境(如分段和生產)而變化。
Spring有一個非常好的功能,您可以在其中擁有一組配置文件(甚至是單個.yaml
文件),並且框架將根據應用程序的運行位置,在分段或生產中自動加載適當的配置值。 這些都在第25章描述。
application-{profile}.properties
或application-{profile}.yml
允許您根據彈簧配置文件自定義應用程序。
可以使用以下命令在{profile}中創建bean:
@Service
@Profile(profile-name)
public class ServiceImpl implements ServiceInterface {
}
還可以基於屬性值和條件創建bean。
@Bean
@ConditionalOnProperty(prefix = EmailProperties.PREFIX, name = "fromId")
public BeanClass bean() {
return new BeanClass(okHttpProperties.getFromId());
}
條件bean可以基於表達式
@Bean
@ConditionalOnExpression("'${spring.datasource.driver-class-name}'=='com.mysql.jdbc.Driver'")
public DbUtil dbMysqlUtil() {
...
}
@Bean
@ConditionalOnExpression("'${spring.datasource.driver-class-name}'=='org.hsqldb.jdbc.JDBCDriver'")
public DbUtil dbHsqlUtil() {
...
}
使configuration.properties文件與舞台和制作分開。 這些配置文件將具有相應的屬性。 現在,在應用程序啟動時,您可以首先根據環境讀取屬性。 您可以在應用程序中作為參數傳遞的環境值。 您只需要編寫一個簡單的ConfigurtionReader
類,它將在應用程序啟動之前讀取所需的配置。 下面是代碼示例,考慮在普通java中讀取一個非常簡單的屬性文件。
這將讀取一個與jar(當前應用程序)並行放置的屬性文件。
public class ConfigurationReader {
/** The job config prop. */
private static final Properties JOB_CONFIG_PROP = new Properties();
/**
* Function is used to read configuration file that is placed in same place
* where project jar is located.
*
*/
public void readConfiguration(final String jobName) {
File jarPath;
String propertiesPath = " ";
String jobConfigFile = " ";
try {
jarPath = new File(ConfigurationReader.class.getProtectionDomain().getCodeSource().getLocation().getPath());
propertiesPath = jarPath.getParentFile().getAbsolutePath();
jobConfigFile = propertiesPath + File.separator + AppConstants.CONFIGURATION_FOLDER_NAME
+ File.separator + jobName + AppConstants.PROP;
JOB_CONFIG_PROP.load(new FileInputStream(jobConfigFile));
} catch (FileNotFoundException fileNtFoundExep) {
throw fileNtFoundExep;
} catch (IOException iOException) {
throw iOException;
} catch (Exception exception) {
throw exception;
}
}
public static String getPropertyValue(final String key) {
return JOB_CONFIG_PROP.getProperty(key);
}
public static void setPropertyValue(final String key, final String value) {
JOB_CONFIG_PROP.setProperty(key, value);
}
}
然后,您可以使用...獲取/設置屬性值
ConfigurationReader.getPropertyValue("abc");
ConfigurationReader.setPropertyValue("abc","xyz");
這只是一種從屬性文件中讀取屬性的簡單方法。 你可以做這樣的事情。
我使用了兩種方法:
指定活動配置文件(例如,application- {profile} .properties)這很好而且很直接。 構建過程將解析特定於環境的屬性文件。 每個env的文件都可以在源代碼管理中維護。 可以在源代碼管理中保護Prod屬性文件(dev / qe無法訪問)。 缺點是管理不同的屬性可能會失去同步(也就是配置漂移)(例如,某個屬性鍵在dev中添加但在qe中沒有添加)
在運行應用程序時指定自定義參數(例如-Dapp.home)您必須添加代碼來自定義加載屬性文件。 某些自定義可以包括處理加密的屬性值。 可以在Chef(或等效工具)中維護屬性鍵/值。 請參閱以下示例代碼:
@Configuration public class MyExternalConfig { @Bean public static PropertyPlaceholderConfigurer configurer(){ //this is an external file path String appHomeConfig = System.getProperty("app.home") + File.separatorChar + "config"; PropertyPlaceholderConfigurer ppc = new PropertyPlaceholderConfigurer(); final Resource extResource = new FileSystemResource( new File( appHomeConfig, "application.properties") ); ppc.setLocations( new Resource[] { extResource } ); //add other properties file if needed ppc.setIgnoreUnresolvablePlaceholders( true ); return ppc; } }
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.