How the Spring @Profile annotation works
Spring profiles let developers configure their applications to behave differently in various environments.
Most Spring profile configurations occur in the application.properties
(or YAML) file. However, with the @Profile
annotation, developers can modify how dependency injection works in different environments, on various targets, and even during local testing.
The ability to switch an implementation class used during testing, as opposed to development or deployment, is particularly useful.
Spring @Profile annotation example
Consider a simple example of testing a number-guessing game. If the application generates a number randomly, testing would be unpredictable; however, random number generation is part of the requirements.
In this case, developers could create two Spring Beans: one generates a random number, and one for testing always returns the same value.
The random number generator is marked with a @Profile(“prod”) annotation, while the one that returns a constant value is marked with @Profile(“test”):
interface NumberGenerator { public int getNumber(); } @Component @Profile("prod") class RandomNumberGenerator implements NumberGenerator { public int getNumber() { return (int)(Math.random() * 10); } } @Component @Profile("dev") class StaticNumberGenerator implements NumberGenerator { public int getNumber() { return 7; } }
Setting the active Spring profile
Which number generator is used at runtime depends on how the active Spring profile is set.
spring.profiles.active=prod
This lets developers test their applications based on predictable results during development, while clients enjoy the excitement of a randomly generated number when the app is in production.
Overriding the active Spring profile
During local development, the active Spring profile is selected based on the contents of the application.properties file. However, developers can override this property by passing a different value as an argument to the virtual machine, which enables them to set the profile differently in each environment.
Any class decorated with @Component
, @Configuration
, or @ConfigurationProperties
can use Spring’s @Profile
annotation to define its environment-specific behavior. This greatly simplifies the development of scalable applications that require customizable configuration across environments.