In Spring, what's the difference between @Profile and @ActiveProfiles
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:
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 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
source to share
Any @Component or @Configuration can be tagged @Profile to be constrained on load.
You define @Profile
for your:
- -directly or indirectly- classes, annotated
@Component
including classes@Configuration
- 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
.
source to share
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.
source to share
@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
.
-
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"}
.
source to share
@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
...
}
source to share