Close

Spring - Profiles

[Last Updated: Dec 22, 2023]
A profile is a named, logical group of bean definitions to be registered with the container only if the given profile is active.

Profiles are useful for running application for different environment e.g. development, test, production etc. We can select/deselect different beans in different environment.

@Profile Annotation

This annotation indicates that the target component is eligible for registration when one or more profiles (specified by this annotation) are active.

Definition of Profile

(Version: spring-framework 6.1.2)
package org.springframework.context.annotation;
   ........
@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Conditional(ProfileCondition.class)
public @interface Profile {
    String[] value(); 
}

The value() attribute specifies the set of profiles for which the annotated component should be registered.

How to Use @Profile annotation?

The @Profile annotation may be used in any of the following ways:

On @Configuration classes

@Configuration
class CommonConfiguration {
}

@Configuration
@Profile("dev")
class LocalConfiguration {

}

@Configuration
@Profile("dev")
class DevConfiguration {
}

@Configuration
@Profile("prod")
class ProdConfiguration {

}

The configurations/beans without profile annotation will be loaded for all profiles or if no profile is active.

On @Bean methods

@Configuration
@Profile("dev")
class DevConfiguration {

  @Profile("qa-tax-service")
  @Bean
  public WebClient taxServiceClient(){
      return ....
  }
}

@Configuration
@Profile("prod")
class ProdConfiguration {

  @Profile("uat-tax-service")
  @Bean
  public WebClient taxServiceClient(){
      return ....
  }
}

How to activate profile(s)?

We can activate profile(s) by one of the following ways:

  • By using the as a JVM system property having
    key: spring.profiles.active
    value: comma separated profile names.
  • Activating profiles programmatically via ConfigurableEnvironment.setActiveProfiles(java.lang.String...)

Naming a profile as default

Naming a Profile as "default" , has special meanings, i.e. if we don't activate any profile during startup, the "default" profile will be loaded along with the beans which don't have any profile associations. If we activate other profile, "default" will not be loaded. We can change "default" profile name by using context.getEnvironment().setDefaultProfiles() or by by using the spring.profiles.default property.

Example

Following example creates two profiles 'dev' (to run in a server environment) and 'local' (to run in a local machine)

Model

public class Customer {
 private String name;

  public Customer(String name) {
      this.name = name;
  }

  @Override
  public String toString() {
      return "Customer{" +
              "name='" + name + '\'' +
              '}';
  }
}

Data access beans

package com.logicbig.example.dao;

import com.logicbig.example.app.Customer;

public interface CustomerDao {
Customer getCustomer(String id);
}
package com.logicbig.example.dao;

import com.logicbig.example.app.Customer;
import org.springframework.stereotype.Repository;

@Repository
public class InMemoryCustomerDao implements CustomerDao{
  @Override
  public Customer getCustomer(String id) {
      return loadCustomerById(id);
  }

  private Customer loadCustomerById(String id) {
      return new Customer("in-memory-customer, id: "+id);
  }
}
package com.logicbig.example.dao;

import com.logicbig.example.app.Customer;
import org.springframework.stereotype.Repository;

@Repository
public class JpaCustomerDao implements CustomerDao{
  @Override
  public Customer getCustomer(String id) {
      return loadCustomerById(id);
  }

  private Customer loadCustomerById(String id) {
      return new Customer("db-loaded-customer, id: "+id);
  }
}

Service beans

package com.logicbig.example.service;

import com.logicbig.example.app.Customer;

public interface OrderService {
  void placeOrder(Customer customer, String orderDetails);
}
package com.logicbig.example.service;

import com.logicbig.example.app.Customer;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile("local")
public class InMemoryOrderService implements OrderService {
  @Override
  public void placeOrder(Customer customer, String orderDetails) {
      System.out.println("InMemoryOrderService: order placed by "+customer+ " details: "+orderDetails);
  }
}
package com.logicbig.example.service;

import com.logicbig.example.app.Customer;
import org.springframework.context.annotation.Profile;
import org.springframework.stereotype.Service;

@Service
@Profile("dev")
public class OrderServiceSimulator implements OrderService{

  @Override
  public void placeOrder(Customer customer, String orderDetails) {
      System.out.println("OrderServiceSimulator: order placed by "+customer+ " details: "+orderDetails);
  }
}

Client bean

package com.logicbig.example.app;

import com.logicbig.example.dao.CustomerDao;
import com.logicbig.example.service.OrderService;
import org.springframework.stereotype.Component;

@Component
public class OrderClient {
 private CustomerDao customerDao;
 private OrderService orderService;

  public OrderClient(CustomerDao customerDao, OrderService orderService) {
      this.customerDao = customerDao;
      this.orderService = orderService;
  }

  public void placeOrder(String customerId){
      Customer customer = customerDao.getCustomer(customerId);
      orderService.placeOrder(customer, "Convertible Thunder");
  }
}

Spring Java Config

package com.logicbig.example;

import com.logicbig.example.dao.CustomerDao;
import com.logicbig.example.dao.InMemoryCustomerDao;
import com.logicbig.example.dao.JpaCustomerDao;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;

@Configuration
public class DataAccessConfig {

  @Bean
  @Profile("local")
  public CustomerDao inMemoryCustomerDao(){
      return new InMemoryCustomerDao();
  }

  @Bean
  @Profile("dev")
  public CustomerDao japCustomerDao(){
      return new JpaCustomerDao();
  }
}

Following class has main method as well, which selects profiles programmatically.

package com.logicbig.example;

import com.logicbig.example.app.OrderClient;
import org.springframework.context.annotation.*;
import org.springframework.core.env.ConfigurableEnvironment;

@Configuration
@ComponentScan({"com.logicbig.example.service", "com.logicbig.example.app"})
@Import(DataAccessConfig.class)
public class AppConfig {

  public static void main(String[] args) {
      runApp("local");
      System.out.println("---------");
      runApp( "dev");
  }

  private static void runApp(String profileName) {
      AnnotationConfigApplicationContext context =
              new AnnotationConfigApplicationContext();
      ConfigurableEnvironment env = context.getEnvironment();
      env.setActiveProfiles(profileName);
      context.register(AppConfig.class);
      context.refresh();

      OrderClient orderClient = context.getBean(OrderClient.class);
      orderClient.placeOrder("customer-1");
  }
}

Output

InMemoryOrderService: order placed by Customer{name='in-memory-customer, id: customer-1'} details: Convertible Thunder
---------
OrderServiceSimulator: order placed by Customer{name='db-loaded-customer, id: customer-1'} details: Convertible Thunder

Example Project

Dependencies and Technologies Used:

  • spring-context 6.1.2 (Spring Context)
     Version Compatibility: 4.3.0.RELEASE - 6.1.2Version List
    ×

    Version compatibilities of spring-context with this example:

    • 4.3.0.RELEASE
    • 4.3.1.RELEASE
    • 4.3.2.RELEASE
    • 4.3.3.RELEASE
    • 4.3.4.RELEASE
    • 4.3.5.RELEASE
    • 4.3.6.RELEASE
    • 4.3.7.RELEASE
    • 4.3.8.RELEASE
    • 4.3.9.RELEASE
    • 4.3.10.RELEASE
    • 4.3.11.RELEASE
    • 4.3.12.RELEASE
    • 4.3.13.RELEASE
    • 4.3.14.RELEASE
    • 4.3.15.RELEASE
    • 4.3.16.RELEASE
    • 4.3.17.RELEASE
    • 4.3.18.RELEASE
    • 4.3.19.RELEASE
    • 4.3.20.RELEASE
    • 4.3.21.RELEASE
    • 4.3.22.RELEASE
    • 4.3.23.RELEASE
    • 4.3.24.RELEASE
    • 4.3.25.RELEASE
    • 4.3.26.RELEASE
    • 4.3.27.RELEASE
    • 4.3.28.RELEASE
    • 4.3.29.RELEASE
    • 4.3.30.RELEASE
    • 5.0.0.RELEASE
    • 5.0.1.RELEASE
    • 5.0.2.RELEASE
    • 5.0.3.RELEASE
    • 5.0.4.RELEASE
    • 5.0.5.RELEASE
    • 5.0.6.RELEASE
    • 5.0.7.RELEASE
    • 5.0.8.RELEASE
    • 5.0.9.RELEASE
    • 5.0.10.RELEASE
    • 5.0.11.RELEASE
    • 5.0.12.RELEASE
    • 5.0.13.RELEASE
    • 5.0.14.RELEASE
    • 5.0.15.RELEASE
    • 5.0.16.RELEASE
    • 5.0.17.RELEASE
    • 5.0.18.RELEASE
    • 5.0.19.RELEASE
    • 5.0.20.RELEASE
    • 5.1.0.RELEASE
    • 5.1.1.RELEASE
    • 5.1.2.RELEASE
    • 5.1.3.RELEASE
    • 5.1.4.RELEASE
    • 5.1.5.RELEASE
    • 5.1.6.RELEASE
    • 5.1.7.RELEASE
    • 5.1.8.RELEASE
    • 5.1.9.RELEASE
    • 5.1.10.RELEASE
    • 5.1.11.RELEASE
    • 5.1.12.RELEASE
    • 5.1.13.RELEASE
    • 5.1.14.RELEASE
    • 5.1.15.RELEASE
    • 5.1.16.RELEASE
    • 5.1.17.RELEASE
    • 5.1.18.RELEASE
    • 5.1.19.RELEASE
    • 5.1.20.RELEASE
    • 5.2.0.RELEASE
    • 5.2.1.RELEASE
    • 5.2.2.RELEASE
    • 5.2.3.RELEASE
    • 5.2.4.RELEASE
    • 5.2.5.RELEASE
    • 5.2.6.RELEASE
    • 5.2.7.RELEASE
    • 5.2.8.RELEASE
    • 5.2.9.RELEASE
    • 5.2.10.RELEASE
    • 5.2.11.RELEASE
    • 5.2.12.RELEASE
    • 5.2.13.RELEASE
    • 5.2.14.RELEASE
    • 5.2.15.RELEASE
    • 5.2.16.RELEASE
    • 5.2.17.RELEASE
    • 5.2.18.RELEASE
    • 5.2.19.RELEASE
    • 5.2.20.RELEASE
    • 5.2.21.RELEASE
    • 5.2.22.RELEASE
    • 5.2.23.RELEASE
    • 5.2.24.RELEASE
    • 5.2.25.RELEASE
    • 5.3.0
    • 5.3.1
    • 5.3.2
    • 5.3.3
    • 5.3.4
    • 5.3.5
    • 5.3.6
    • 5.3.7
    • 5.3.8
    • 5.3.9
    • 5.3.10
    • 5.3.11
    • 5.3.12
    • 5.3.13
    • 5.3.14
    • 5.3.15
    • 5.3.16
    • 5.3.17
    • 5.3.18
    • 5.3.19
    • 5.3.20
    • 5.3.21
    • 5.3.22
    • 5.3.23
    • 5.3.24
    • 5.3.25
    • 5.3.26
    • 5.3.27
    • 5.3.28
    • 5.3.29
    • 5.3.30
    • 5.3.31
    • Compatible Java Version: 17+
    • 6.0.0
    • 6.0.1
    • 6.0.2
    • 6.0.3
    • 6.0.4
    • 6.0.5
    • 6.0.6
    • 6.0.7
    • 6.0.8
    • 6.0.9
    • 6.0.10
    • 6.0.11
    • 6.0.12
    • 6.0.13
    • 6.0.14
    • 6.0.15
    • 6.1.0
    • 6.1.1
    • 6.1.2

    Versions in green have been tested.

  • JDK 17
  • Maven 3.8.1

Spring Profile Example Select All Download
  • spring-profile-example
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • app
                • dao
                • service
                • AppConfig.java

    See Also