library
intermediateProperties & Configuration Loading
Load configuration from .properties files, system properties, and environment variables in the right order.
Configuration lives outside the code, so one build can run in every environment.
Configuration loading = a stack of transparent sheets. Each sheet (source) has some settings filled in. You read from top to bottom — the first sheet with a value wins. Command-line is on top, defaults are on the bottom.
Key Concepts
1
# app.properties
db.url=jdbc:postgresql://localhost/shop
db.pool.size=10
feature.newCheckout=false2
Properties p = new Properties();
try (var in = getClass().getResourceAsStream("/app.properties")) {
p.load(in);
}
String url = p.getProperty("db.url");
int size = Integer.parseInt(p.getProperty("db.pool.size", "5"));3
The sources, highest precedence first.
-Dkey=value command line system property
environment variable System.getenv("DATABASE_URL")
a properties file on the classpath or on disk
a default in code the last resort4
That order is the point. The same artifact runs anywhere because anything can be overridden without
rebuilding.
5
Properties is a Hashtable subclass, which is a historical wart — it is synchronized, and its keys and
values are typed Object even though it stores strings. getProperty is the string-typed accessor to use.
PropertiesHashtableObjectgetProperty
6
The file format has details worth knowing.
key=value key:value key value all valid
# comment ! comment
long=one \
continued a trailing backslash continues the line7
Encoding is the trap. load(InputStream) reads ISO-8859-1, so a non-ASCII value arrives mangled. Use the
reader overload:
load(InputStream)
8
p.load(new InputStreamReader(in, StandardCharsets.UTF_8));9
Never put secrets in a properties file. They end up committed. Pass them as environment variables, or
read them from a secret manager at startup.
10
Validate at startup, not on first use.
if (p.getProperty("db.url") == null)
throw new IllegalStateException("db.url is required");11
A missing setting that fails immediately costs minutes. One that fails on an uncommon code path three days
later costs far more.
12
Spring Boot does all of this for you — application.yml, profiles like application-prod.yml, @Value
and @ConfigurationProperties with validation. The precedence rules are the same idea, with more sources.
application.ymlapplication-prod.yml@Value@ConfigurationProperties
13
What the interviewer is probing.1. "Why does a non-ASCII value come out mangled from Properties.load?" Probing: the encoding
default. Stalls: "The file is wrong." Moves up: load(InputStream) reads ISO-8859-1; use the
Reader overload with UTF-8.
14
2. "Where should secrets live?" Probing: whether you draw the line. Stalls: "In the
properties file, it is not in git." Moves up: never in the file — environment variables or a
secret manager, because property files get committed sooner or later.
15
3. "What is a sensible precedence order?" Probing: externalised configuration. Stalls:
"Whatever loads last." Moves up: command-line system properties, then environment, then file, then
a default in code — so anything can be overridden without rebuilding.
16
4. "Why validate configuration at startup?" Probing: failure timing. Stalls: "It will fail
when used." Moves up: a missing setting that fails immediately costs minutes; one that fails on an
uncommon path three days later costs far more.