Spring Environment, Profiles and SpEL

Environment

Represents loaded properties from runtime environments.

Properties are derived from multiple sources:

  • JVM System properties -> System.getProperty()
  • System Env. variables -> System.getenv()
  • Java properties files

Profiles

Beans can be grouped in profiles, these can represent environment, implementation or deployment platforms.

Configuration:

@Configuration
@Profile("embedded")
public class DevConfig {...}

or

@Configuration
public class Config {

 @Bean(name="datasource")
 @Profile("embedded")
 public Datasource getDataSourceDev(){
 ...
 }

 @Bean(name="datasource")
 @Profile("!embedded")
 public Datasource getDataSourceProd(){
 ...
 }

}

Activate profile:

-Dspring.profiles.active=embedded,jpa

System.setProperty(“spring.profiles.active”,”embedded,jpa”)

Tests

Tests profile can be annotated with: @ActiveProfiles(“dev”)

https://www.baeldung.com/spring-profiles

@Value

@Value can be used in:

Constructor

@Autowired
public TransferServiceImpl(@Value("${daily.limit}") int max){
...
}

Method

@Autowired
public int setDailyLimit(@Value("${daily.limit}") int max){
...
}

Value

@Value("${daily.limit}")
int max;

@SpEL

Accessing properties: $ – value, # – expression/execution

Get value: @Value(“${bean.message}”)

Get system environment variable: @Value(“#{systemEnvironment[‘SOME_ENV_VARIABLE’]}”)

It cast to the required type:

@Value(“${daily.limit}”)
int maxTransferPerDay;
@Value(“#{environment[‘daily.limit’]}”)
int maxTransferPerDay;

But values are handled as String:

@Value(“#{new Integer(environment[‘daily.limit’]) * 2 }”) -> OK
@Value (“#{new java.net.URI(environment[‘home.page’]).host}”) -> OK
@Value (“#{daily.limit * 2}”}) -> not OK

Default values:

@Value(“${daily.limit:1000}”)
@Value(“#{environment[‘daily.limit’]?:1000}”)