2017-06-06 126 views
4

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

這裏是我的代碼,

EmailUtility.java

package com.housecar.common; 

public class EmailUtility { 

//For staging 
public static final String FROM_EMAIL_ID = "[email protected]"; 
public static final String FROM_NAME = "xyz"; 
static final String SMTP_USERNAME = "[email protected]"; 
static final String SMTP_PASSWORD = "15sss67$"; 
public static final String REPLY_EMAIL_ID = "[email protected]"; 
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 = "[email protected]"; 
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 = "[email protected]"; 
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";*/ 

} 

在我的代碼,我手動註釋掉的配置!

+3

你應該看看屬性文件。 –

+0

你有沒有使用任何屬性文件或類似的東西。 ?? –

+0

什麼是動態的?在運行應用程序時更改配置還是僅僅通過啓動? – Patrick

回答

2

你可以使用屬性文件來解決你的問題,就像你可以有兩個屬性文件取決於環境。

1)config_staging.properties 2)config_production.properties

和移動暫存電子郵件配置config_staging.properties,將您的產品配置config_production.properties。

將在運行應用程序時進行配置。

例如,

config_staging.properties

smtp.username = "[email protected]"; 
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; 
1

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

例如,像這樣的一個表:

CREATE TABLE configuration (
    key varchar(255), 
    value varchar(255) 
); 

哪裏key是屬性名稱和value是屬性值。

甲屬性

environment=development 

可能成爲

INSERT INTO configuration (key, value) VALUES('environment', 'development'); 
2

您應該從屬性存儲裝置(例如其由Java類Properties類處理屬性文件)查找系統dependend值。

但是,您不應該在同一個文件中提供所有系統信息。

您應該有單獨的文件(具有相同的名稱),讓您的部署過程將目標系統的文件複製到預期的位置。

通過這種方式,您可以讓操作團隊使用您(作爲開發人員)不應該知道的數據來操作(或預先配置)屬性文件,例如。密碼高安全性系統...

2

添加以下到您的application.properties文件:

from.email.id = [email protected] 
from.name = xyz 

... 

你啓動應用程序之前,您定義這些屬性(取決於您EVN你的情況) 。 當然,你需要將它們注入類如下:

@Value("${from.email.id}") 
private String fromEmailId; 

所以現在fromEmailId將給予進入application.properties文件中的值。

祝你好運。

編輯:

如果你想安全的一點點更高的水平,你可以使用jasypt來CRIPT您的密碼到您的applicaiton.properties文件。最後,密碼將如下所示:

smtp.password = ENC(5KZL2q+Ute21FzCsJy/h0aIp75TZgHBHx8L11R+jTJs0=) 
+1

你在最後一行的'application.properties'中有一個錯字 –

-1

使stage.properties文件與stage和production分開。這些配置文件將具有相應的屬性。現在,在啓動應用程序時,您可以先根據環境讀取屬性。環境值,您可以在應用程序中將其作爲參數傳遞。您只需編寫一個簡單的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

釷這裏的其他答案是朝正確方向邁出的一步。

一些建議將配置值移動到.properties文件中。這是朝着正確方向邁出的一大步,但忽略了使用Spring Boot的事實。

一些建議將配置值移入彈出application.propertiesapplication.yaml文件。這對於Spring應用程序來說是更好的選擇。 application.properties實際上只是第一個建議的.properties文件,但是會被Spring框架自動加載。這全部在Spring Boot Reference GuideChapter 24. Externalized Configuration中描述。

但是,你的問題居然說:

[...] 常見配置電子郵件發送者相關的,基於像臨時和生產環境的配置變化。

春天有一個非常不錯的功能,在這裏你可以有一組配置文件(甚至單個.yaml文件),框架會自動加載相應的配置值,這取決於應用程序正在運行,其中,在舞臺或製作中。這全部在Chapter 25. Profiles中描述。

1

application-{profile}.propertiesapplication-{profile}.yml允許您根據彈簧配置文件自定義您的應用程序。

有可能使用僅創建在{輪廓}豆:

@Service 
@Profile(profile-name) 
public class ServiceImpl implements ServiceInterface { 
} 

此外,也可以創建基於屬性值和條件豆。

@Bean 
@ConditionalOnProperty(prefix = EmailProperties.PREFIX, name = "fromId") 
public BeanClass bean() { 
    return new BeanClass(okHttpProperties.getFromId()); 
} 

條件豆可以基於表達

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

我已經使用兩種方法:

  1. 指定有效簡 (例如應用程序 - {輪廓}的.properties。)這很好,很簡單。構建過程將解析特定於環境的屬性文件。每個env的文件都可以在源代碼管理中維護。 Prod屬性文件(dev/qe不可訪問)可以在源代碼管理中加以保護。缺點是管理不同的屬性可能會失去同步(又名配置漂移)(例如某個屬性鍵被添加到設備中,但不在qe中)

  2. 指定運行應用程序時的自定義參數(例如, -Dapp.home) 您必須添加代碼來自定義加載屬性文件。一些定製可以包括處理加密的屬性值。屬性鍵/值可以在廚師(或同等工具)中維護。請參見下面的示例代碼:

    @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; 
        } 
    }