在JAVA中,如何根据环境动态选择配置?

在JAVA中,如何根据环境动态选择配置?,java,spring,spring-boot,constants,Java,Spring,Spring Boot,Constants,我有一个实用程序类,它具有与电子邮件发送者相关的常见配置,配置会根据环境而变化,如暂存和生产。现在,如何根据环境动态选择配置 这是我的密码 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

我有一个实用程序类,它具有与电子邮件发送者相关的常见配置,配置会根据环境而变化,如
暂存
生产
。现在,如何根据环境动态选择配置

这是我的密码

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";*/

}

在我的代码中,我手动注释了配置

在spring中,您可以使用或设置外部配置

否则,如果在运行应用程序时需要更改配置,并且正在使用数据库,则可以在数据库中创建一个配置表,其中包含键值configs,并在代码中读取它们

例如,像这样的表:

CREATE TABLE configuration (
    key varchar(255),
    value varchar(255)
);
其中,
是属性名称,
是属性值

财产

environment=development
可能成为

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

您应该从属性存储中查找依赖于系统的值(例如,由Javas
properties
class处理的属性文件)

但不应在同一文件中提供所有系统信息

您应该有单独的文件(名称相同),并让部署过程将目标系统的文件复制到预期位置


通过这种方式,您可以让运营团队使用您(作为开发人员)不应该知道的数据操作(或预配置)属性文件,例如高安全系统的密码…

将以下内容添加到您的
应用程序中。属性
文件:

from.email.id = xx12@xyz.com
from.name = xyz

...
e、 t.c

在启动应用程序之前定义这些属性(取决于您的evn)。 当然,您需要将它们注入到您的类中,如下所示:

@Value("${from.email.id}")
private String fromEmailId;
因此,现在
fromEmailId
将具有给定到
application.properties
文件中的值

祝你好运

编辑:

如果您想要更高一点的安全级别,可以使用
jasypt
将您的密码编写到
applicationon.properties
文件中。最后,密码将如下所示:

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

将configuration.properties文件与阶段和生产分开。这些配置文件将具有相应的属性。现在,当应用程序启动时,您可以首先读取基于环境的属性。可以在应用程序中作为参数传递的环境值。您只需要编写一个简单的
ConfigurtionReader
类,它将在应用程序启动之前读取所需的配置。下面是考虑用普通java读取非常简单的属性文件的代码示例

这将读取与jar(当前应用程序)并行放置的属性文件

然后,您可以使用获取/设置属性值

ConfigurationReader.getPropertyValue("abc");
ConfigurationReader.setPropertyValue("abc","xyz");

这只是从属性文件中读取属性的一种简单方法。您可以这样做。

您可以使用属性文件来解决问题,就像您可以根据环境拥有两个属性文件一样

1) config_staging.properties 2) config_production.properties

 smtp.username = "xx12@xyz.com";
 smtp.password = "15sss67$";
smtp.username = "AKYeeeELEQAGAA";
smtp.password = "gvwwwwwbgpGm/C/LmUYUK5HosQar7mTSwjl5MFeBRR";
并将登台电子邮件配置移动到config_staging.properties,将生产配置移动到config_production.properties

将在运行应用程序时对其进行配置

比如说,

config_staging.properties

 smtp.username = "xx12@xyz.com";
 smtp.password = "15sss67$";
smtp.username = "AKYeeeELEQAGAA";
smtp.password = "gvwwwwwbgpGm/C/LmUYUK5HosQar7mTSwjl5MFeBRR";
config_production.properties

 smtp.username = "xx12@xyz.com";
 smtp.password = "15sss67$";
smtp.username = "AKYeeeELEQAGAA";
smtp.password = "gvwwwwwbgpGm/C/LmUYUK5HosQar7mTSwjl5MFeBRR";
然后将它们注入EmailUtility类

@Value("${smtp.username}")
private String smtpUsername;


@Value("${smtp.password}")
private String smtpPassword;

这里的其他答案是朝着正确方向迈出的一步

有些人建议将配置值移动到
.properties
文件中。这是朝着正确方向迈出的一大步,但忽略了您正在使用SpringBoot这一事实

有些人建议将配置值移动到Spring
application.properties
application.yaml
文件中。这是Spring应用程序的更好选择
application.properties
实际上只是一个类似于第一次建议的
.properties
文件,但是由Spring框架自动加载。这些都在的中进行了描述

但是,你的问题实际上是:

[…]常见配置与电子邮件发送者相关,配置会根据登台和生产等环境进行更改


Spring有一个非常好的特性,您可以拥有一组配置文件(甚至是一个
.yaml
文件),框架将根据应用程序在暂存或生产中的运行位置自动加载适当的配置值。这些都在中进行了描述。

应用程序-{profile}.properties
应用程序-{profile}.yml
允许您根据spring概要文件自定义应用程序

可以使用以下方法仅在{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() {
    ...
}

我使用了两种方法:

  • 指定活动配置文件(例如应用程序-{profile}.properties) 这很好,而且很直截了当。生成过程将解析特定于环境的属性文件。可以在源代码管理中维护每个环境的文件。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;
        }
    }
    

  • 你应该查看属性文件。你没有使用任何属性文件或类似的东西吗??什么是动态?运行应用程序时更改配置或仅通过