@Profile in Spring Boot

@Profile in Spring Boot

Where Can We Apply the @Profile Annotation?

The `@Profile` annotation in Spring Boot can be applied in several places to conditionally create beans based on the active profile. You can apply it on:

Now let’s explore these use cases in more detail with examples.

Example 1: @Profile on RestTemplate Beans

Let’s say you want to create a `RestTemplate` bean for calling an API. You need two beans: one with basic authentication and one with secured SSL and token-based authentication. However, you only want one bean to be active based on the profile. You can define it as shown below:


@Configuration
public class RestTemplateConfig {

    @Bean
    @Profile("local")
    public RestTemplate localRestTemplate() {
        return new RestTemplate();
    }

    @Bean
    @Profile("aws-east")
    public RestTemplate awsRestTemplate() {
        return new RestTemplate(new HttpComponentsClientHttpRequestFactory());
    }
}
        

In this example:

  • When the `local` profile is active, the `localRestTemplate` bean will be created.
  • When the `aws-east` profile is active, the `awsRestTemplate` bean will be created.

Example 2: @Profile on Interface Implementations

Another common use of `@Profile` is on the class level. For example, if you have an interface with two implementations, you can decide which implementation to use based on the active profile.


public interface MyService {
    String getServiceDetails();
}

@Profile("local")
@Component
public class UnsecureServiceImpl implements MyService {
    @Override
    public String getServiceDetails() {
        return "Unsecure service for local environment";
    }
}

@Profile("aws-east")
@Component
public class SecureServiceImpl implements MyService {
    @Override
    public String getServiceDetails() {
        return "Secure service for AWS-East environment";
    }
}
        

In this case:

  • If the `local` profile is active, `UnsecureServiceImpl` will be used.
  • If the `aws-east` profile is active, `SecureServiceImpl` will be used.

Example 3: @Profile on Configuration Classes

You can also use `@Profile` on entire configuration classes. This allows you to load different configurations depending on the active profile.


@Configuration
@Profile("dev","local")
public class DevConfig {
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create()
                .url("jdbc:mysql://localhost:3306/dev_db")
                .username("dev_user")
                .password("dev_pass")
                .build();
    }
}

@Configuration
@Profile("prod")
public class ProdConfig {
    @Bean
    public DataSource dataSource() {
        return DataSourceBuilder.create()
                .url("jdbc:mysql://localhost:3306/prod_db")
                .username("prod_user")
                .password("prod_pass")
                .build();
    }
}
        

In this case:

  • If the `dev` or `local` profile is active, the `DevConfig` class will be loaded, and a development database connection will be created.
  • If the `prod` profile is active, the `ProdConfig` class will be loaded, and a production database connection will be created.

Defining and Using Active Profiles in Spring Boot

Spring Boot allows you to define different configurations for various profiles and easily switch between them. This is achieved by creating profile-specific configuration files and specifying the active profile. Here’s how you can define and use them:

1. Define Configuration in Profile-Specific Files

Spring Boot supports profile-specific configuration files. You can create files like:

  • application-dev.yaml for the dev profile.
  • application-prod.yaml for the prod profile.

Each of these files can contain different properties that will be applied when the respective profile is active. For instance:


    # application-dev.yaml
    server.port: 8081
    spring.datasource.url: jdbc:mysql://localhost:3306/dev_db
        

    # application-prod.yaml
    server.port: 8080
    spring.datasource.url: jdbc:mysql://prod-db-server:3306/prod_db
        

2. Activate Profiles

To activate a specific profile, you can specify it in several places:

  • In the application.properties or application.yaml file: spring.profiles.active=dev (or any other active profile like prod).
  • As a command-line argument: --spring.profiles.active=dev (used when running the app via the command line).
  • As a VM argument: -Dspring.profiles.active=dev (used when starting the application with a specific VM option).

3. Priority of Profile-Specific Configurations

When both the general application.yaml and profile-specific files (like application-dev.yaml) define the same property, the value in the profile-specific file will take precedence. For example:

  • If application.yaml defines a property and application-dev.yaml also defines the same property, the value from application-dev.yaml will be used when the dev profile is active.