В Spring какая разница между @Profile и @ActiveProfiles

В чем разница между использованием @Profile и @ActiveProfiles в конфигурации Spring Test

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

и

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

Ответ 1

Короче говоря, @Profile определяет профиль, такой как профиль отладки, профиль производства и т.д. Однако @ActiveProfiles появляется на рисунке в случае ApplicationContext и определяет, какие профили должны быть активными, если используется соответствующий ApplicationContext.

Как упоминалось на официальном сайте JavaDoc of Spring:

@Профиль

Профиль - это именованная логическая группа, которая может быть активирована программно через ConfigurableEnvironment.setActiveProfiles(java.lang.String...) или декларативно, установив свойство spring.profiles.active как системное свойство JVM, как переменную среды или как параметр контекста сервлета в web.xml для веб-приложений. Профили также можно активировать декларативно в интеграционных тестах с помощью аннотации @ActiveProfiles.

@ActiveProfiles

ActiveProfiles - это аннотация уровня класса, которая используется для объявления, какие профили определения активных компонентов следует использовать при загрузке ApplicationContext для тестовых классов.

Кроме того, вы можете увидеть здесь для получения дополнительной информации о @Profile

Ответ 2

Любой @Component или @Configuration можно пометить @Profile для ограничения при загрузке.

Вы определяете @Profile для своего:

  1. классы -directly или indirectly-, аннотированные @Component, включая классы @Configuration
  2. методы, аннотированные @Bean

Затем во время тестирования вы выбираете, какой профиль (профили) вы хотите, указав их в @ActiveProfiles.

ActiveProfiles - это аннотация уровня класса, которая используется для объявления, какие профили определения активных компонентов следует использовать при загрузке ApplicationContext для тестовых классов.

Он не действует, если используется вне контекста теста.

Резюме

Вы назначаете профиль своим компонентам с помощью @Profile; во время тестирования выберите их с помощью @ActiveProfiles, а при разработке выберите их с spring.profiles.active свойства spring.profiles.active.

Ответ 3

Профили Spring предоставляют способ разделения частей конфигурации вашего приложения.

Любой @Component или @Configuration может быть помечен @Profile для ограничения при загрузке, что означает, что компонент или конфигурация будут загружены в контексте приложения только тогда, когда активные профили совпадают с профилем, сопоставленным с компонентом.

Чтобы пометить профиль активным, свойство spring.profiles.active должно быть установлено в application.properties или задано в качестве аргумента виртуальной машины как -Dspring.profiles.active=dev

При написании 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());
    }
}

Итак, если вы хотите запустить свои тестовые примеры junit в профиле dev вам нужно использовать @ActiveProfile('dev'). Это загрузит бин DataSourceConfig, определенный в профиле разработчика.

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

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

}

Заключение

@Profile используется для отображения класса в профиль

@ActiveProfile используется для активации определенных профилей во время выполнения тестового класса junit.

Ответ 4

@Profile используется при объявлении компонента или конфигурации. @Profile объявляет, к какому профилю принадлежит бин или конфигурация.

@ActiveProfiles используется только из тестов, которые потребляют боб или конфигурацию, чтобы включить один или несколько профилей.

Если @ActiveProfiles, он заставляет Spring Context проверять, @Profile ли компонент или конфигурация @Profile. Если это так, этот компонент или конфигурация загружается только в том случае, если профиль в @ActiveProfiles соответствует правилу профиля в аннотации компонента @Profile.

Ответ 5

  • с @Profile аннотации @Profile вы @Profile условие для вашего определения компонента, что влияет на создание или отсутствие создания этого компонента в контексте @Profile в зависимости от текущих активных профилей. Пример из JavaDoc:

    @Profile({"p1", "!p2"} - регистрация произойдет, если профиль 'p1' активен или если профиль 'p2' не активен.

  • с @ActiveProfiles вы устанавливаете текущие активные профили. Пример:

    @ActiveProfiles({"p2","p3"}) с аннотацией @Profile({"p1", "!p2"} не будет создан.

    @ActiveProfiles({"p3"}) с аннотацией @Profile({"p1", "!p2"}.

    @ActiveProfiles({"p1"}) с аннотацией @Profile({"p1", "!p2"}.

Ответ 6

@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 свойства spring.profiles.active либо путем аннотирования класса:

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