Spring Core: Configuration & Environment ๐
The Magic Settings Box
Imagine your house has a magic settings box. This box knows:
- Whatโs your favorite room temperature
- Whether itโs daytime or nighttime
- Which family member is home
Your Spring application has a similar magic box! Letโs explore it.
๐ฏ The Big Picture
graph TD A[Your App] --> B[Environment] B --> C[Property Sources] B --> D[Profiles] C --> E[application.properties] C --> F[System Variables] C --> G[Command Line Args] D --> H[dev profile] D --> I[prod profile] D --> J[test profile]
Think of it like this:
- Property Sources = Different places to keep your settings
- Environment = The helper who reads those settings
- Profiles = Different modes for your app (like game difficulty levels!)
๐ฆ Property Sources: Where Settings Live
What Are Property Sources?
Think about where you keep important notes:
- A notebook on your desk
- Sticky notes on the fridge
- Reminders on your phone
Property Sources are places where Spring keeps app settings!
The Priority Tower
Spring checks settings from TOP to BOTTOM:
๐ Command Line Arguments (Highest Priority)
โ
System Environment Variables
โ
application.properties
โ
๐ป Default Values (Lowest Priority)
Like a child asking for ice cream:
- First asks Dad (command line)
- Then Mom (environment variable)
- Then Grandma (properties file)
Whoever says YES first wins!
Example: Setting the Server Port
In application.properties:
server.port=8080
Using Environment Variable:
SERVER_PORT=9090
Using Command Line:
java -jar app.jar --server.port=3000
If all three exist, command line wins (port 3000)!
Reading Properties in Code
@Value("${server.port}")
private int port;
This is like saying: โHey Spring, whatโs the server port?โ
Custom Property Files
You can create your own settings files!
# myapp.properties
app.name=Super Cool App
app.version=1.0
Then tell Spring about it:
@PropertySource("classpath:myapp.properties")
@Configuration
public class AppConfig {
// Your config here
}
๐ Environment Abstraction: The Settings Reader
What is Environment?
Environment is like a super-smart assistant who:
- Knows all your settings
- Knows which profile is active
- Can answer any question about configuration
The Environment Interface
public interface Environment {
String[] getActiveProfiles();
boolean acceptsProfiles(String... profiles);
String getProperty(String key);
}
Think of these methods:
getActiveProfiles()โ โWhat mode am I in?โacceptsProfiles()โ โAm I in this mode?โgetProperty()โ โWhatโs the value of X?โ
Using Environment in Your Code
Step 1: Inject Environment
@Autowired
private Environment env;
Step 2: Ask Questions
// Get a property
String dbUrl = env.getProperty("database.url");
// Get with default value
String name = env.getProperty(
"app.name",
"Default App"
);
// Check if property exists
if (env.containsProperty("feature.enabled")) {
// do something
}
Real-World Example
@Service
public class GreetingService {
@Autowired
private Environment env;
public String greet() {
String name = env.getProperty(
"app.greeting.name",
"Friend"
);
return "Hello, " + name + "!";
}
}
With app.greeting.name=World in properties:
- Returns: โHello, World!โ
Without the property:
- Returns: โHello, Friend!โ
๐ญ Profiles: Different Modes for Your App
What Are Profiles?
Imagine a video game with difficulty levels:
- Easy Mode โ Development (dev)
- Normal Mode โ Testing (test)
- Hard Mode โ Production (prod)
Each mode has different settings!
Why Use Profiles?
| Profile | Database | Debug Logs | Security |
|---|---|---|---|
| dev | Local H2 | ON | Relaxed |
| test | Test DB | ON | Medium |
| prod | Real DB | OFF | Strict |
Creating Profile-Specific Properties
File: application-dev.properties
database.url=jdbc:h2:mem:devdb
logging.level.root=DEBUG
File: application-prod.properties
database.url=jdbc:mysql://prod-server
logging.level.root=WARN
Spring automatically picks the right file!
Activating Profiles
Method 1: In application.properties
spring.profiles.active=dev
Method 2: Command Line
java -jar app.jar --spring.profiles.active=prod
Method 3: Environment Variable
SPRING_PROFILES_ACTIVE=prod
@Profile Annotation
Make beans appear only in certain profiles!
@Configuration
@Profile("dev")
public class DevConfig {
@Bean
public DataSource dataSource() {
// Returns H2 in-memory database
return new H2DataSource();
}
}
@Configuration
@Profile("prod")
public class ProdConfig {
@Bean
public DataSource dataSource() {
// Returns MySQL database
return new MySqlDataSource();
}
}
In dev mode: Uses H2 database In prod mode: Uses MySQL database
Magic! Same code, different behavior!
Multiple Profiles
You can activate several profiles at once:
spring.profiles.active=dev,logging,metrics
This activates ALL three profiles!
Checking Active Profile in Code
@Autowired
private Environment env;
public void checkProfile() {
if (env.acceptsProfiles(
Profiles.of("prod"))) {
System.out.println("We're in PROD!");
}
}
Default Profile
What if NO profile is active?
spring.profiles.default=dev
Now dev runs if nothing else is specified!
๐ How Everything Connects
graph TD A[Application Starts] --> B[Load Property Sources] B --> C[Check Active Profiles] C --> D[Load Profile Properties] D --> E[Environment Ready] E --> F[Beans Can Ask Questions] F --> G[App Runs with Settings]
The Flow in Simple Words
- App starts โ โLet me check my settingsโ
- Loads properties โ From files, env vars, command line
- Checks profile โ โAm I in dev or prod mode?โ
- Loads profile files โ Gets application-dev.properties etc.
- Environment ready โ โI know everything now!โ
- Beans ask questions โ โWhatโs my database URL?โ
- App runs โ With the right settings!
๐ฎ Quick Examples
Example 1: Feature Toggle
# application.properties
feature.newDesign=false
# application-beta.properties
feature.newDesign=true
@Value("${feature.newDesign}")
private boolean useNewDesign;
public String getPage() {
if (useNewDesign) {
return "new-page.html";
}
return "old-page.html";
}
Activate beta profile โ New design appears!
Example 2: Different APIs
@Service
@Profile("mock")
public class MockPaymentService {
public void pay() {
System.out.println("Fake payment!");
}
}
@Service
@Profile("!mock") // NOT mock
public class RealPaymentService {
public void pay() {
// Real payment logic
}
}
Use ! to mean โNOT this profileโ!
๐ Summary
| Concept | What It Does | Analogy |
|---|---|---|
| Property Sources | Store settings | Notebooks with notes |
| Environment | Read settings | Assistant who knows everything |
| Profiles | Different modes | Game difficulty levels |
Key Takeaways
- Property Sources have priority order (command line wins!)
- Environment is your go-to for reading any setting
- Profiles let you have different settings for dev/prod
- Use
@Profileto make beans profile-specific - Use
@ValueorEnvironmentto read properties
๐ You Did It!
You now understand:
- โ Where Spring keeps settings (Property Sources)
- โ How to read settings (Environment)
- โ How to have different modes (Profiles)
Your Spring apps can now be smart chameleons โ changing behavior based on where they run!
Next step: Try creating application-dev.properties and application-prod.properties in your project. See the magic happen!