Place application.properties under src/main/resources. Spring Boot picks it up automatically — no extra configuration needed.
# Server
server.port=8080
# DataSource
spring.datasource.url=jdbc:postgresql://localhost:5432/mydb
spring.datasource.username=appuser
spring.datasource.password=secret
# Custom app properties
app.name=My Application
app.max-retries=3
app.timeout-seconds=30
@Value injects a single property from the environment. A default value can be supplied after the colon.
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
@Service
public class RetryService {
@Value("${app.max-retries:3}") // defaults to 3 if not set
private int maxRetries;
@Value("${app.timeout-seconds:30}")
private int timeoutSeconds;
@Value("${app.name}")
private String appName;
public void performWithRetry(Runnable task) {
for (int i = 0; i < maxRetries; i++) {
try {
task.run();
return;
} catch (RuntimeException e) {
System.err.println("Retry " + (i + 1) + " of " + maxRetries);
}
}
throw new RuntimeException("Max retries exceeded");
}
}
@ConfigurationProperties maps a group of related properties to a strongly-typed POJO. This is more maintainable than multiple @Value annotations and supports Bean Validation via @Validated.
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;
@Component
@ConfigurationProperties(prefix = "app")
public class AppProperties {
private String name;
private int maxRetries;
private int timeoutSeconds;
// Spring binds: app.name -> name, app.max-retries -> maxRetries, etc.
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getMaxRetries() { return maxRetries; }
public void setMaxRetries(int v) { this.maxRetries = v; }
public int getTimeoutSeconds() { return timeoutSeconds; }
public void setTimeoutSeconds(int v) { this.timeoutSeconds = v; }
}
Inject the properties class wherever needed:
@Service
public class NotificationService {
private final AppProperties props;
public NotificationService(AppProperties props) {
this.props = props;
}
public void notify(String msg) {
System.out.println("[" + props.getName() + "] " + msg);
}
}
YAML is supported natively and is often preferred for nested configuration thanks to its cleaner hierarchical syntax.
server:
port: 8080
spring:
datasource:
url: jdbc:postgresql://localhost:5432/mydb
username: appuser
password: secret
app:
name: My Application
max-retries: 3
timeout-seconds: 30
Both application.properties and application.yml work interchangeably with @Value and @ConfigurationProperties.