In Spring, what's the difference between @Profile and @ActiveProfiles

What is the difference between using @Profile and @ActiveProfiles in Spring Test configuration

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

      

and

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

      

+20


source to share


6 answers


In short, @Profile

defines a profile like debug profile, production profile, etc. However, it @ActiveProfiles

appears in the figure in case and determines which profiles should be active if the appropriate one is used . ApplicationContext

ApplicationContext

As mentioned on the official JavaDoc of Spring website:

@Profile

A profile is a named logical group that can be activated programmatically via ConfigurableEnvironment.setActiveProfiles (java.lang.String ...) or declaratively by setting the spring.profiles.active property as a JVM system property, as an environment variable, or as a servlet context parameter in web.xml for web applications. Profiles can also be activated declaratively in integration tests using the @ActiveProfiles annotation.



@ActiveProfiles

ActiveProfiles is a class-level annotation that is used to declare which active component definition profiles to use when loading the ApplicationContext for test classes.

Also, you can see here for more information on @Profile

+7


source


Any @Component or @Configuration can be tagged @Profile to be constrained on load.

You define @Profile

for your:

  1. -directly or indirectly- classes, annotated @Component

    including classes@Configuration

  2. methods annotated @Bean

Then during testing, you choose which profile (s) you want by specifying them in @ActiveProfiles

.



ActiveProfiles is a class-level annotation that is used to declare which active component definition profiles to use when loading the ApplicationContext for test classes.

It has no effect when used outside the context of a test.

Summary

You assign a profile to your components with @Profile

; during testing select them with @ActiveProfiles

, and during development select them from spring.profiles.active

properties spring.profiles.active

.

+3


source


Spring profiles provide a way to separate parts of your application's configuration.

Any @Component

or @Configuration

can be marked @Profile

to be restricted on load, which means that a component or configuration will only be loaded in the application context when the active profiles match the profile associated with the component.

To mark a profile as active, the property spring.profiles.active

must be set to application.properties

or given as an argument to the virtual machine as-Dspring.profiles.active=dev

When writing Junit, you would like to activate some profile in order to load the required configuration or component. The same can be done using annotation @ActiveProfile

.

Consider a configuration class that is associated with a profile 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());
    }
}

      

Consider a configuration class that is associated with a profile 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());
    }
}

      

So if you want to run your junit test cases in profile dev

you need to use @ActiveProfile('dev')

. This will load the DataSourceConfig bean defined in the developer profile.

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

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

}

      

Conclusion

@Profile

used to display a class in profile

@ActiveProfile

used to activate certain profiles during the execution of the junit test class.

+2


source


@Profile

used when declaring a component or config. @Profile

declares which profile a bean or configuration belongs to.

@ActiveProfiles

only used from tests that consume a bean or config to include one or more profiles.

If @ActiveProfiles

, it forces Spring Context to check @Profile

if component or config @Profile

. If so, this component or configuration is loaded only if the profile @ActiveProfiles

matches the profile rule in the component annotation @Profile

.

+1


source


  • with @Profile

    annotation @Profile

    you are a @Profile

    condition for your component definition, which affects whether or not this component is created in context @Profile

    depending on the currently active profiles. Example from JavaDoc:

    @Profile({"p1", "!p2"}

    - registration will occur if profile 'p1' is active or if profile 'p2' is not active.

  • with @ActiveProfiles

    you set the currently active profiles. Example:

    @ActiveProfiles({"p2","p3"})

    with annotation will @Profile({"p1", "!p2"}

    not be created.

    @ActiveProfiles({"p3"})

    with annotation @Profile({"p1", "!p2"}

    .

    @ActiveProfiles({"p1"})

    with annotation @Profile({"p1", "!p2"}

    .

0


source


@Profile

used to define different definitions @Bean

for different contexts, for example:

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();
    }
}

      

If you have this configuration, when starting the application, all you have to do is indicate which profile is active, either from a spring.profiles.active

property spring.profiles.active

or by annotating the class:

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

      

0


source







All Articles