簡體   English   中英

如何根據JAVA中的環境動態選擇配置?

[英]How to dynamically choose the configurations based on the environment in JAVA?

我有一個實用程序類,它具有與電子郵件發件人相關的常見配置,配置會根據環境(如StagingProduction更改。 現在我如何根據環境動態選擇配置?

這是我的代碼,

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;

在Spring中,您可以使用屬性yaml設置外部配置。

否則,如果您需要在運行應用程序時更改配置並且正在使用數據庫,則可以使用鍵值配置在數據庫中創建配置表,並在代碼中讀取它們。

例如,像這樣的表:

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.propertiesapplication.yaml文件中。 這是Spring應用程序的更好選擇。 application.properties實際上只是一個像第一個建議的.properties文件,但是由Spring Framework自動加載。 這在第24章Spring Boot參考指南的 外部化配置”中有所描述。

但是,你的問題實際上說:

[...]與電子郵件發件人相關的常見配置 ,配置根據環境(如分段和生產)而變化。

Spring有一個非常好的功能,您可以在其中擁有一組配置文件(甚至是單個.yaml文件),並且框架將根據應用程序的運行位置,在分段或生產中自動加載適當的配置值。 這些都在第25章描述。

application-{profile}.propertiesapplication-{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");

這只是一種從屬性文件中讀取屬性的簡單方法。 你可以做這樣的事情。

我使用了兩種方法:

  1. 指定活動配置文件(例如,application- {profile} .properties)這很好而且很直接。 構建過程將解析特定於環境的屬性文件。 每個env的文件都可以在源代碼管理中維護。 可以在源代碼管理中保護Prod屬性文件(dev / qe無法訪問)。 缺點是管理不同的屬性可能會失去同步(也就是配置漂移)(例如,某個屬性鍵在dev中添加但在qe中沒有添加)

  2. 在運行應用程序時指定自定義參數(例如-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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM