如何从系统变量设置 Spring 配置文件?

Posted

技术标签:

【中文标题】如何从系统变量设置 Spring 配置文件?【英文标题】:How to set Spring profile from system variable? 【发布时间】:2016-11-26 00:21:02 【问题描述】:

我有一个使用另一个项目的 Spring 项目。每个项目都有自己的 spring 配置文件,使用 applicationContext.xml*.properties 为每个配置文件从 java 代码初始化。我从args[] 注入配置文件。 问题是第二个项目使用来自 applicationContext.xml 的默认环境配置 我无法将来自args[] 的环境注入到第二个项目中,我尝试寻找一篇解释 Spring 配置文件如何工作的文章。

    applicationContext.xml 未配置默认值时,是否有一个层次结构来查看配置文件? System var 是否比 applicationContext.xml 配置强? 您认为应对我的挑战的最佳解决方案是什么?

非常感谢有关该主题的文章甚至示例! 提前致谢。

【问题讨论】:

【参考方案1】:

如果您为您的 JVM 提供 Spring 配置文件,则应该没有问题:

java -Dspring.profiles.active=development -jar yourApplication.jar 

另见 Spring 文档:

http://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html

69.5 设置活动的 Spring 配置文件

Spring 环境对此有一个 API,但通常你会设置 系统属性(spring.profiles.active)或操作系统环境 变量(SPRING_PROFILES_ACTIVE)。例如。启动你的应用程序 -D 参数(记得放在主类或jar包之前):

$ java -jar -Dspring.profiles.active=生产 demo-0.0.1-SNAPSHOT.jar

在 Spring Boot 中,您还可以在 application.properties,例如

spring.profiles.active=生产

以这种方式设置的值被系统属性或环境替换 变量设置,但不是由 SpringApplicationBuilder.profiles() 方法。因此后一个 Java API 可用于扩充配置文件 无需更改默认值。

请参阅第 25 章,“Spring Boot 特性”部分中的配置文件以了解 更多信息。

【讨论】:

【参考方案2】:

我的解决方案是将环境变量设置为spring.profiles.active=development。这样在该机器上运行的所有应用程序都将引用该变量并启动应用程序。 spring加载一个属性的顺序如下

application.properties
system properties
environment variable

【讨论】:

【参考方案3】:

如果我从我的 web 应用程序目录运行命令行:java -Dspring.profiles.active=development -jar yourApplication.jar,它表明路径不正确。所以我只是在 application.properties 文件中手动定义了配置文件,如下所示:

spring.profiles.active=mysql 

spring.profiles.active=postgres

spring.profiles.active=mongodb

【讨论】:

【参考方案4】:

SPRING_PROFILES_ACTIVE 是覆盖/选择 Spring 配置文件的环境变量

【讨论】:

与 Docker 一起也可以很好地与 TypeSafe config (HOCON) 库、用于初始化应用程序/系统/Docker 容器等的 Shell 脚本配合使用。 参考:docs.spring.io/spring-boot/docs/current/reference/html/…【参考方案5】:

如果你使用docker部署spring boot app,你可以使用e标志设置profile

docker run -e "SPRING_PROFILES_ACTIVE=prod" -p 8080:8080 -t r.test.co/myapp:最新的

【讨论】:

这个标志如何在 spring 内部使用。 @ParmarKamlesh 标志 -e 用于在 docker 容器内传递 env 变量。由于 Spring 读取 SPRING_PROFILES_ACTIVE env var 以获取活动配置文件,因此 docker 的 -e 标志有效。【参考方案6】:

我通常使用 基于注释的配置而不是 基于 XML 的配置来配置 applicationContext。无论如何,我相信他们都有相同的优先级

*回答你的问题,系统变量优先级更高*


从 applicationContext 获取基于配置文件的 bean

在 Bean 上使用 @Profile

@Component
@Profile("dev")
public class DatasourceConfigForDev

现在,个人资料是dev

注意:如果配置文件被指定为 @Profile("!dev") 然后配置文件将排除 dev 并适用于所有其他人。

在 XML 中使用配置文件属性

<beans profile="dev">
    <bean id="DatasourceConfigForDev" class="org.skoolguy.profiles.DatasourceConfigForDev"/>
</beans>

设置配置文件的值:

通过 WebApplicationInitializer 接口以编程方式

在 Web 应用程序中,可以使用 WebApplicationInitializer 以编程方式配置 ServletContext
@Configuration
public class MyWebApplicationInitializer implements WebApplicationInitializer 

    @Override
    public void onStartup(ServletContext servletContext) throws ServletException 
            servletContext.setInitParameter("spring.profiles.active", "dev");
    

通过 ConfigurableEnvironment 以编程方式

您还可以直接在环境中设置配置文件:
    @Autowired
    private ConfigurableEnvironment env;

    // ...

    env.setActiveProfiles("dev");

web.xml 中的上下文参数

配置文件也可以在 Web 应用程序的 web.xml 中激活,使用上下文参数:
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>/WEB-INF/app-config.xml</param-value>
    </context-param>
    <context-param>
        <param-name>spring.profiles.active</param-name>
        <param-value>dev</param-value>
    </context-param>

JVM系统参数

作为参数传递的配置文件名称将在应用程序启动期间激活:

-Dspring.profiles.active=dev

在 IDE 中,您可以设置应用程序运行时要使用的环境变量和值。以下是Eclipse中的运行配置:

环境变量

通过命令行设置:export spring_profiles_active=dev

任何未指定配置文件的 bean 都属于“默认”配置文件。


优先顺序是:

    web.xml 中的上下文参数 WebApplicationInitializer JVM系统参数 环境变量

【讨论】:

【参考方案7】:

您可以通过提供-Dspring.profiles.active=&lt;env&gt;来设置弹簧配置文件

source(src)目录中的java文件,可以通过 System.getProperty("spring.profiles.active")

对于 test 目录 中的 java 文件,您可以提供

SPRING_PROFILES_ACTIVE&lt;env&gt;

因为“环境”、“jvmArgs”和“systemProperties”对于“测试”任务会被忽略。在 root build.gradle 添加一个任务来设置 jvm 属性和环境变量。

test 
    def profile = System.properties["spring.profiles.active"]
    systemProperty "spring.profiles.active",profile
    environment "SPRING.PROFILES_ACTIVE", profile
    println "Running $project tests with profile: $profile"

【讨论】:

【参考方案8】:

参加聚会为时已晚,但以下是该主题的新趋势:https://howtodoinjava.com/spring-boot2/logging/profile-specific-logging/

这是一个很好的例子:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <include resource="org/springframework/boot/logging/logback/defaults.xml" />
  <property name="LOG_FILE" value="c:/temp/spring.log"/>
  <include resource="org/springframework/boot/logging/logback/console-appender.xml" />
  
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <encoder>
      <pattern>$FILE_LOG_PATTERN</pattern>
    </encoder>
    <file>$LOG_FILE</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>$LOG_FILE.%d</fileNamePattern>
    </rollingPolicy>
  </appender>
  
  <springProfile name="local | dev">
    <logger name="org.springframework" level="DEBUG" additivity="false">
        <appender-ref ref="CONSOLE" />
    </logger>
    <root level="DEBUG">
      <appender-ref ref="CONSOLE" />
      <appender-ref ref="FILE" />
    </root>
  </springProfile>
 
  <springProfile name="prod">
    <root level="INFO">
      <appender-ref ref="FILE" />
    </root>
  </springProfile>
 
  <springProfile name="!local & !dev & !prod">
    <root level="INFO">
      <appender-ref ref="FILE" />
    </root>
  </springProfile>
  
</configuration>

!注意!如果您在使用 &amp;amp; 时遇到问题,请将其替换为 &amp;amp;

【讨论】:

【参考方案9】:

之前的大多数答案要么已经过时,要么无缘无故地过于复杂。

此时,您可以像这样在 application.properties 中轻松设置活动配置文件:

spring.profiles.active=YOUR_PROFILE

YOUR_PROFILE 是……您的个人资料

我多次使用它,其中大部分是我将数据源与其存储库、实体、控制器等隔离开来...

【讨论】:

以上是关于如何从系统变量设置 Spring 配置文件?的主要内容,如果未能解决你的问题,请参考以下文章

spring boot importsource怎么设置加载顺序

如何配置Spring的环境变量

01Spring Boot配置文件相关

winform程序如何加密配置文件

Spring Boot 配置的优先级

如何设置classpath