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

132

我有一个使用另一个项目的Spring项目。每个项目都有自己的Spring配置文件applicationContext.xml和每个配置文件对应的*.properties文件。我通过args[]注入配置文件中的环境参数。 问题在于第二个项目使用了默认的环境配置,而不是从applicationContext.xml中获取。 我无法将args[]中的环境参数注入到第二个项目中,并且尝试查找一篇解释Spring配置文件工作原理的文章。

  1. 如果在applicationContext.xml中未设置默认值,它会按照层次结构查找配置文件吗?
  2. 系统变量是否比applicationContext.xml配置更强?
  3. 您认为最好的解决方案是什么?

非常感谢任何关于这个主题的文章或者例子。


1
请注意:除了“官方来源”(官方文档等)之外,不允许请求其他学习资源,因为这往往会吸引带有个人观点的答案和垃圾信息(请参阅[帮助/主题])。 - starball
8个回答

204

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


除了Docker之外,它还可以很好地与TypeSafe配置(HOCON)库一起使用,以及用于初始化应用程序/系统/Docker容器的Shell脚本等。 - Lalit Jha
4
好的,我会尽力进行翻译。以下是需要翻译的内容:参考文献:https://docs.spring.io/spring-boot/docs/current/reference/html/howto-properties-and-configuration.html#howto-set-active-spring-profiles - Alan

91

如果您向JVM提供了Spring配置文件,就不应该会出现问题:

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

同时请参阅 Spring-Documentation:

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

69.5 设置活动的Spring配置文件

Spring Environment 提供了一个API,但通常您会设置系统属性(spring.profiles.active)或操作系统环境 变量(SPRING_PROFILES_ACTIVE)。例如,使用-D参数启动应用程序(记得将其放在主类或jar档案之前):

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

在Spring Boot中,您还可以在application.properties中设置活动配置文件,例如:

spring.profiles.active=production

通过这种方式设置的值将被系统属性或环境变量的设置所替换,但不会受到SpringApplicationBuilder.profiles() 方法的影响。因此,后者的Java API可用于增加配置文件而不更改默认值。

有关更多信息,请参见“Spring Boot特性”部分中的第25章,“配置文件”。


56

我通常使用基于注释的配置来配置applicationContext,而不是基于XML的配置。 无论如何,我认为它们两个具有相同的优先级

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


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

  • 在Bean上使用@Profile

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

现在,配置文件是dev

注意:如果配置文件为@Profile("!dev"),则该配置文件将排除dev并适用于其他所有配置文件。

  • 在XML中使用profiles属性

<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 System Parameter

    The profile names passed as the parameter will be activated during application start-up:

    -Dspring.profiles.active=dev
    

    In IDEs, you can set the environment variables and values to use when an application runs. The following is the Run Configuration in Eclipse:

Eclipse Run Configuration - 截图不可用

  • 环境变量

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

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


优先级排序:

  1. web.xml中的Context参数
  2. WebApplicationInitializer接口实现类
  3. JVM系统参数
  4. 环境变量

你有关于优先顺序的参考资料吗? - ryanwebjackson

17

如果您使用docker部署spring boot应用程序,可以使用标志e设置配置文件

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


请注意,此处的“prod”是您要激活的配置文件的名称。您可以更改它以匹配您的实际需求。

这个标志在Spring内部是如何使用的? - Parmar Kamlesh
1
@ParmarKamlesh 标志“-e”用于在Docker容器内传递环境变量。由于Spring读取“SPRING_PROFILES_ACTIVE”环境变量以获取活动配置文件,因此Docker的-e标志有效。 - CᴴᴀZ

7

您可以通过提供-Dspring.profiles.active=<env>来设置Spring配置文件。

对于源(src)目录中的Java文件,您可以使用System.getProperty("spring.profiles.active")

对于测试(test)目录中的Java文件,您可以提供:

  • SPRING_PROFILES_ACTIVE<env>

或者

由于"test"任务忽略了"environment"、"jvmArgs"和"systemProperties"。在根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}"
}

2
我的解决方案是将环境变量设置为spring.profiles.active=development。这样,在该计算机上运行的所有应用程序都将引用该变量并启动应用程序。Spring加载属性的顺序如下:
application.properties
system properties
environment variable

2
如果我在我的Web应用程序目录中运行命令行:java -Dspring.profiles.active=development -jar yourApplication.jar,它会显示路径不正确。因此,我只需手动在application.properties文件中定义配置文件,如下所示:
spring.profiles.active=mysql 

或者

spring.profiles.active=postgres

or

spring.profiles.active=mongodb

0

虽然来晚了,但这是该话题的新趋势: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;替换。


那个 XML 数据块的文件名是什么? - MarkHu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接