Externalised configuration lets the same jar run in dev, test and production.
Spring Boot reads configuration from src/main/resources/application.properties (or application.yml). Hundreds of built-in properties tune auto-configured components: server.port=8081, spring.datasource.url=..., logging.level.org.springframework.web=DEBUG, spring.jackson.serialization.indent-output=true.
Values can come from many sources, and later ones override earlier ones. The most important, from lower to higher priority:
application.propertiesinside the jar;application.propertiesnext to the jar (or in./config/);- environment variables, using relaxed binding:
SERVER_PORT=9000setsserver.port; - command-line arguments:
java -jar app.jar --server.port=9000.
This is how one artifact runs everywhere: defaults in the jar, environment-specific values injected by the platform.
Your own settings work the same way. Inject a single value with @Value("${app.greeting}"), with a default after a colon: @Value("${app.retries:3}"). Properties can reference others: app.url=http://${app.host}:${server.port}. For anything more than one or two values, prefer typed @ConfigurationProperties classes (a later lesson).
Never commit secrets in application.properties; supply them through environment variables or a secret manager.
Example
# src/main/resources/application.properties
server.port=8081
spring.application.name=shop
app.greeting=Hello from ${spring.application.name}
logging.level.com.example=DEBUG
// GreetingController.java
@RestController
class GreetingController {
private final String greeting;
private final int retries;
GreetingController(@Value("${app.greeting}") String greeting,
@Value("${app.retries:3}") int retries) { // default 3
this.greeting = greeting;
this.retries = retries;
}
@GetMapping("/greet")
String greet() { return greeting + " (retries=" + retries + ")"; }
}
// GET :8081/greet -> Hello from shop (retries=3)
// SERVER_PORT=9000 java -jar shop.jar -> now listens on 9000Remember
application.properties/.ymlconfigure Boot and your own code- Environment variables and command-line args override packaged values
@Value("${key:default}")injects one value- Keep secrets out of the repository
Watch out for
- Hard-coding environment-specific URLs in the jar instead of overriding them per environment.