【问题标题】:In Spring what is the difference between @Profile and @ActiveProfiles在 Spring 中,@Profile 和 @ActiveProfiles 有什么区别
【发布时间】:2017-05-18 19:06:09
【问题描述】:

在 Spring Test 配置中使用 @Profile 和 @ActiveProfiles 有什么区别

@Configuration
@EnableRetry
@ActiveProfiles("unittest") 
static class ContextConfiguration {

@Configuration
@EnableRetry
@Profile("unittest") 
static class ContextConfiguration {

【问题讨论】:

  • @ActiveProfilesorg.springframework.test 的一部分,我假设它习惯于在测试期间加载配置文件。 @Profile 用于定义/命名配置文件特定配置。我从未使用过@ActiveProfiles,所以这只是我的逻辑猜测。
  • 我在这里遇到了这个答案,它似乎通常回答了我的问题stackoverflow.com/a/27216503/277023

标签: java spring


【解决方案1】:

Spring Profiles 提供了一种分离应用程序配置部分的方法。

任何@Component@Configuration 都可以用@Profile 标记以限制加载时间,这意味着只有当活动配置文件与映射到的配置文件相同时,组件或配置才会在应用程序上下文中加载组件。

要将配置文件标记为活动,必须在application.properties 中设置spring.profiles.active 属性或作为-Dspring.profiles.active=dev 的VM 参数给出

在编写 Junit 时,您可能希望激活一些配置文件以加载所需的配置或组件。使用@ActiveProfile注解也可以达到同样的效果。

考虑一个映射到配置文件dev的配置类

@Configuration
@Profile("dev")
public class DataSourceConfig {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:mysql://localhost/test");
        ds.setUsername("root");
        ds.setPassword("mnrpass");
        return ds;
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }
}

考虑一个映射到配置文件prod的配置类

@Configuration
@Profile("prod")
public class DataSourceConfig {
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("com.mysql.jdbc.Driver");
        ds.setUrl("jdbc:oracle://xxx.xxx.xx.xxx/prod");
        ds.setUsername("dbuser");
        ds.setPassword("prodPass123");
        return ds;
    }

    @Bean
    public JdbcTemplate jdbcTemplate() {
        return new JdbcTemplate(dataSource());
    }
}

因此,如果您想在 dev 配置文件中运行您的 junit 测试用例,那么您必须使用 @ActiveProfile('dev') 注释。这将加载在 dev 配置文件中定义的 DataSourceConfig bean。

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
@ActiveProfiles("dev")
public class Tests{

    // Junit Test cases will use the 'dev' profile DataSource Configuration

}

结论

@Profile 用于将类映射到配置文件

@ActiveProfile 用于在 junit 测试类执行期间激活特定配置文件

【讨论】:

    【解决方案2】:

    简而言之,@Profile 定义了一个配置文件,如调试配置文件和生产配置文件等......但是,@ActiveProfiles 出现在ApplicationContext 的情况下,并定义了如果相应的ApplicationContext 应该激活哪些配置文件正在使用中。

    Spring官网JavaDoc中提到:

    @Profile

    配置文件是一个命名的逻辑分组,可以通过 ConfigurableEnvironment.setActiveProfiles(java.lang.String...) 以编程方式激活,或者通过将 spring.profiles.active 属性设置为 JVM 系统属性、环境变量以声明方式激活,或作为 web.xml 中的 Servlet 上下文参数用于 Web 应用程序。配置文件也可以通过 @ActiveProfiles 注释在集成测试中以声明方式激活。

    @ActiveProfiles

    ActiveProfiles 是一个类级别的注解,用于声明在为测试类加载 ApplicationContext 时应该使用哪些活动 bean 定义配置文件。

    你也可以see here for more information about @Profile

    【讨论】:

      【解决方案3】:

      任何@Component 或@Configuration 都可以用@Profile 标记来限制 加载时。

      您为您定义@Profile

      1. 直接或间接使用@Component 注释的类,包括@Configuration
      2. @Bean注释的方法

      然后在测试时,您可以通过在@ActiveProfiles 中指定您想要的配置文件来选择它们。

      ActiveProfiles 是一个类级别的注解,用于声明 加载时应使用哪些活动 bean 定义配置文件 test 类的 ApplicationContext。

      如果在测试上下文之外使用它没有效果。

      总结

      您使用@Profile 将配置文件分配给您的组件;测试时使用@ActiveProfiles 选择它们,而开发时使用spring.profiles.active 属性选择它们。

      【讨论】:

        【解决方案4】:

        @Profile用于为不同的上下文定义不同的@Bean定义,例如:

        public class BeanConfiguration {
            @Bean
            @Profile({"local", "dev", "ci-dev", "homolog"})
            public SomeHttpClientBean adyenClientFactorySandbox() {
                return SomeHttpClientBean.builder()
                    .url("https://test.example.com")
                    .build();
            }
        
            @Bean
            @Profile("prod")
            public SomeHttpClientBean adyenClientFactorySandbox() {
                return SomeHttpClientBean.builder()
                    .url("https://production.example.com")
                    .build();
            }
        }
        

        一旦您有了该配置,在启动您的应用程序时,您只需通过spring.profiles.active 属性或通过注释类来设置哪个配置文件处于活动状态:

        @RunWith(SpringRunner.class)
        @SpringBootTest(classes = Application.class)
        @ActiveProfiles("ci-dev")
        public class SpringBootTestBase {
            @Test
            ...
        }
        

        【讨论】:

          【解决方案5】:
          • 使用@Profile 注释,您可以为 bean 定义设置条件,这会影响在您的 spring 上下文中创建或不创建此 bean,具体取决于当前活动配置文件。 JavaDoc 中的示例:

            @Profile({"p1", "!p2"} - 如果配置文件“p1”处于活动状态,将进行注册 如果配置文件“p2”处于活动状态。

          • 使用@ActiveProfiles,您可以设置当前的活动配置文件。示例:

            @ActiveProfiles({"p2","p3"}) 带有注释 @Profile({"p1", "!p2"} 的 bean 将不会被创建。

            将创建带有注释@Profile({"p1", "!p2"}@ActiveProfiles({"p3"}) bean。

            将创建带有注释@Profile({"p1", "!p2"}@ActiveProfiles({"p1"}) bean。

          【讨论】:

            【解决方案6】:

            @Profile声明 bean 或配置时使用。 @Profile 声明 bean 或配置属于哪个配置文件。

            @ActiveProfiles 仅用于使用 bean 或配置以启用一个或多个配置文件的测试。

            @ActiveProfiles被指定时,它会导致Spring Context检查一个bean或配置是否被@Profile注解。如果是这样,则仅当 @ActiveProfiles 中的配置文件与 bean 的 @Profile 注释中的配置文件规则匹配时才会加载该 bean 或配置。

            【讨论】:

              猜你喜欢
              • 2013-05-06
              • 1970-01-01
              • 2021-06-12
              • 1970-01-01
              • 2011-05-07
              • 2013-03-05
              • 1970-01-01
              • 1970-01-01
              • 2019-04-18
              相关资源
              最近更新 更多