3.1.2 激活 profile

Spring 在确定哪个 profile 处于激活状态时,需要依赖两个独立的属性:spring.profiles.activespring.profiles.default。如果设置了 spring.profiles.active 属性的话,那么它的值就会用来确定哪个 profile 是激活的。但如果没有设置 spring.profiles.active 属性的话,那 Spring 将会查找 spring.profiles.default 的值。如果 spring.profiles.activepring.profiles.default 均没有设置的话,那就没有激活的 profile,因此只会创建那些没有定义在 profile 中的 bean。

有多种方式来设置这两个属性:

  • 作为 DispatcherServlet 的初始化参数;

  • 作为 Web 应用的上下文参数;

  • 作为 JNDI 条目;

  • 作为环境变量;

  • 作为 JVM 的系统属性;

  • 在集成测试类上,使用 @ActiveProfiles 注解设置。

你尽可以选择 spring.profiles.activespring.profiles.default 的最佳组合方式以满足需求,我将这样的自主权留给读者。

我所喜欢的一种方式是使用 DispatcherServlet 的参数将 spring.profiles.default 设置为开发环境的 profile,我会在 Servlet 上下文中进行设置(为了兼顾到 ContextLoaderListener)。例如,在 Web 应用中,设置 spring.profiles.default 的 web.xml 文件会如下所示:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
         xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
           http://xmlns.jcp.org/xml/ns/javaee/web-app_2_5.xsd" >
  
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>/WEB-INF/spring/root-context.xml</param-value>
  </context-param>
  
  <context-param>
    <param-name>spring.profiles.default</param-name>
    <param-name>dev</param-name>
  </context-param>
  
  <listener>
    <listener-class>
      org.springframework.web.context.ContextLoaderListener
    </listener-class>
  </listener>
  
  <servlet>
    <servlet-name>appServlet</servlet-name>
    <servlet-class>
      org.springframework.web.servlet.DispatcherServlet
    </servlet-class>
    <init-param>
      <param-name>spring.profile.default</param-name>
      <param-value>dev</param-value>
    </init-param>
    <load-on-startup>1</load-on-startup>
  </servlet>
  
  <servlet-mapping>
    <servlet-name>appServlet</servlet-name>
    <url-pattern>/</url-pattern>
  </servlet-mapping>

</web-app>

按照这种方式设置 spring.profiles.default,所有的开发人员都能从版本控制软件中获得应用程序源码,并使用开发环境的设置(如嵌入式数据库)运行代码,而不需要任何额外的配置。

当应用程序部署到 QA、生产或其他环境之中时,负责部署的人根据情况使用系统属性、环境变量或 JNDI 设置 spring.profiles.active 即可。当设置 spring.profiles.active 以后,至于 spring.profiles.default 置成什么值就已经无所谓了;系统会优先使用 spring.profiles.active 中所设置的 profile。

你可能已经注意到了,在 spring.profiles.activespring.profiles.default 中,profile 使用的都是复数形式。这意味着你可以同时激活多个 profile,这可以通过列出多个 profile 名称,并以逗号分隔来实现。当然,同时启用 dev 和 prod profile 可能也没有太大的意义,不过你可以同时设置多个彼此不相关的profile。

使用 profile 进行测试

当运行集成测试时,通常会希望采用与生产环境(或者是生产环境的部分子集)相同的配置进行测试。但是,如果配置中的 bean 定义在了 profile 中,那么在运行测试时,我们就需要有一种方式来启用合适的 profile。

Spring 提供了 @ActiveProfiles 注解,我们可以使用它来指定运行测试时要激活哪个 profile。在集成测试时,通常想要激活的是开发环境的 profile。例如,下面的测试类片段展现了使用 @ActiveProfiles 激活 dev profile:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes={PersistenceTestConfig.class})
@ActiveProfile("dev")
public class PersistenceTest {
  ...
}

在条件化创建 bean 方面,Spring 的 profile 机制是一种很棒的方法,这里的条件要基于哪个 profile 处于激活状态来判断。Spring 4.0 中提供了一种更为通用的机制来实现条件化的 bean 定义,在这种机制之中,条件完全由你来确定。让我们看一下如何使用 Spring 4 和 @Conditional 注解定义条件化的 bean。

Last updated