Woche 2, Tag 3 — Spring Profiles: dev, test, prod und @Profile
Ziel
Heute verstehst du Spring Profiles.
Die Kernfragen:
- Was ist ein Spring Profile?
- Warum brauchen wir Profiles?
- Wie funktionieren
application-dev.yml,application-test.ymlundapplication-prod.yml? - Wie aktivierst du ein Profile?
- Was macht
@Profile? - Kannst du mehrere aktive Profiles haben?
- Was bedeutet
@Profile("!prod")? - Wie wirken Profiles auf Beans?
- Wie wirken Profiles auf Konfigurationsdateien?
- Welche typischen Prüfungsfallen gibt es?
1. Kurz-Wiederholung von Tag 2
An Tag 2 hast du gelernt:
- Externe Konfiguration hält umgebungsspezifische Werte außerhalb des Java-Codes.
- Spring Boot liest Konfiguration aus
application.properties,application.yml, Environment Variables, Command-Line-Argumenten und mehr. @Valueinjiziert einen einzelnen Wert.@ConfigurationPropertiesbindet gruppierte Konfiguration.- Environment Variables können Datei-Konfiguration überschreiben.
- Secrets gehören nicht in Git.
Merksatz:
@Value ist für einen Wert.
@ConfigurationProperties ist für gruppierte Config.
Heute lernst du, wie du für verschiedene Umgebungen unterschiedliche Konfiguration nutzt.
2. Was ist ein Spring Profile?
Ein Spring Profile ist ein Weg, für verschiedene Umgebungen unterschiedliche Konfiguration oder Beans zu aktivieren.
Häufige Profiles:
dev
test
prod
local
docker
ci
staging
Kurze Definition:
Ein Spring Profile ist ein benannter Umgebungsmodus, der steuert, welche Konfiguration und welche Beans aktiv sind.
Beispiel:
dev = lokale Entwicklung
test = automatisierte Tests
prod = Production
3. Warum brauchen wir Profiles?
Verschiedene Umgebungen brauchen unterschiedliche Einstellungen.
Beispiel:
Lokale Entwicklung
spring:
datasource:
url: jdbc:postgresql://localhost:5432/app_dev
Production
spring:
datasource:
url: jdbc:postgresql://prod-db:5432/app_prod
Gleicher Code.
Unterschiedliche Konfiguration.
Genau dafür sind Profiles da.
4. Praxisbeispiel
Stell dir eine Spring-Boot-App mit E-Mail-Versand vor.
In der Entwicklung willst du keine echten E-Mails verschicken.
In Production willst du echte E-Mails.
Dafür kannst du haben:
dev profile -> FakeEmailSender
prod profile -> RealEmailSender
Beispiel:
public interface EmailSender {
void send(String to, String message);
}
@Service
@Profile("dev")
public class FakeEmailSender implements EmailSender {
@Override
public void send(String to, String message) {
System.out.println("Fake email to " + to);
}
}
@Service
@Profile("prod")
public class RealEmailSender implements EmailSender {
@Override
public void send(String to, String message) {
// send real email
}
}
Ist dev aktiv, erzeugt Spring FakeEmailSender.
Ist prod aktiv, erzeugt Spring RealEmailSender.
5. Profile-spezifische Config-Dateien
Spring Boot unterstützt profile-spezifische Konfigurationsdateien.
Häufige Dateien:
application.yml
application-dev.yml
application-test.yml
application-prod.yml
Basisdatei:
## application.yml
spring:
application:
name: klarsync
server:
port: 8080
Development-Datei:
## application-dev.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/klarsync_dev
username: postgres
password: postgres
logging:
level:
org.springframework: INFO
Production-Datei:
## application-prod.yml
spring:
datasource:
url: jdbc:postgresql://prod-db:5432/klarsync
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
logging:
level:
org.springframework: WARN
6. Wie Spring Profile-Config lädt
Ist kein Profile aktiv, lädt Spring:
application.yml
Ist das dev-Profile aktiv, lädt Spring:
application.yml
application-dev.yml
Ist das prod-Profile aktiv, lädt Spring:
application.yml
application-prod.yml
Profile-spezifische Werte können Basiswerte überschreiben.
Merksatz:
application.ymlist die Basis-Config.application-dev.ymlüberschreibt sie, wenndevaktiv ist.
7. Beispiel: Werte überschreiben
Basisdatei:
## application.yml
server:
port: 8080
app:
name: klarsync
email-enabled: true
Dev-Datei:
## application-dev.yml
server:
port: 8081
app:
email-enabled: false
Ist dev aktiv:
server.port = 8081
app.name = klarsync
app.email-enabled = false
server.port wird überschrieben.
app.email-enabled wird überschrieben.
app.name bleibt aus der Basisdatei.
8. Wie du ein Profile aktivierst
Es gibt mehrere Wege.
Option 1 — In application.yml
spring:
profiles:
active: dev
Das funktioniert, ist aber für Production nicht immer empfehlenswert — die Profile-Auswahl sollte oft aus der Umgebung kommen.
Option 2 — Command Line
java -jar app.jar --spring.profiles.active=prod
Option 3 — Environment Variable
SPRING_PROFILES_ACTIVE=prod java -jar app.jar
Das ist in Docker und Production üblich.
Option 4 — IDE Run Configuration
In IntelliJ kannst du hinzufügen:
-Dspring.profiles.active=dev
oder als Environment Variable:
SPRING_PROFILES_ACTIVE=dev
Option 5 — Test-Annotation
In Tests:
@SpringBootTest
@ActiveProfiles("test")
class TaskServiceTest {
}
Damit aktivierst du das test-Profile für den Test.
9. Best Practice für die Profile-Aktivierung
Für lokale Entwicklung ist dev in der IDE in Ordnung.
Für Production bevorzugst du Environment Variables oder Deployment-Config.
Gut:
SPRING_PROFILES_ACTIVE=prod
Vermeide, die Production-Profile-Aktivierung in Git zu committen:
spring:
profiles:
active: prod
Warum?
Weil lokale oder Test-Umgebungen sonst versehentlich Production-Konfiguration nutzen können.
10. @Profile
@Profile steuert, ob eine Bean für ein bestimmtes Profile erzeugt wird.
Beispiel:
@Service
@Profile("dev")
public class FakeEmailSender implements EmailSender {
}
Diese Bean wird nur erzeugt, wenn das dev-Profile aktiv ist.
Beispiel:
@Service
@Profile("prod")
public class RealEmailSender implements EmailSender {
}
Diese Bean wird nur erzeugt, wenn das prod-Profile aktiv ist.
11. @Profile auf @Bean-Methoden
@Profile kannst du auch auf @Bean-Methoden setzen.
@Configuration
public class EmailConfig {
@Bean
@Profile("dev")
public EmailSender fakeEmailSender() {
return new FakeEmailSender();
}
@Bean
@Profile("prod")
public EmailSender realEmailSender() {
return new RealEmailSender();
}
}
Ist dev aktiv, erzeugt Spring fakeEmailSender.
Ist prod aktiv, erzeugt Spring realEmailSender.
12. @Profile auf Configuration-Klassen
Du kannst @Profile auf eine ganze Configuration-Klasse setzen.
@Configuration
@Profile("dev")
public class DevConfig {
@Bean
public DataInitializer dataInitializer() {
return new DataInitializer();
}
}
Diese ganze Configuration-Klasse ist nur in dev aktiv.
Ist dev nicht aktiv, ignoriert Spring diese Configuration-Klasse und ihre Beans.
13. Mehrere Profiles
Spring kann mehrere aktive Profiles haben.
Beispiel:
java -jar app.jar --spring.profiles.active=dev,docker
Aktive Profiles:
dev
docker
Spring lädt dann:
application.yml
application-dev.yml
application-docker.yml
Beans mit einem der Profiles können aktiv werden.
Beispiel:
@Profile("dev")
aktiv, wenn dev aktiv ist.
@Profile("docker")
aktiv, wenn docker aktiv ist.
14. Profile-Ausdrücke
@Profile unterstützt einfache Ausdrücke.
Nicht-Profile
@Profile("!prod")
Bedeutung:
Aktiv, wenn prod NICHT aktiv ist.
Beispiel:
@Service
@Profile("!prod")
public class ConsoleEmailSender implements EmailSender {
}
Diese Bean ist in dev, test oder anderen Non-Prod-Umgebungen aktiv.
UND-Ausdruck
@Profile("dev & docker")
Bedeutung:
Aktiv nur, wenn sowohl dev als auch docker aktiv sind.
ODER-Ausdruck
@Profile("dev | test")
Bedeutung:
Aktiv, wenn dev oder test aktiv ist.
15. Häufige Profile-Ausdrücke
| Ausdruck | Bedeutung | |
|---|---|---|
dev | aktiv, wenn dev aktiv ist | |
prod | aktiv, wenn prod aktiv ist | |
!prod | aktiv, wenn prod nicht aktiv ist | |
| `dev | test` | aktiv, wenn dev oder test aktiv ist |
dev & docker | aktiv, wenn sowohl dev als auch docker aktiv sind |
16. Praxisbeispiel: Dev vs. Prod E-Mail
Interface:
public interface EmailSender {
void send(String to, String message);
}
Dev-Implementierung:
@Service
@Profile("dev")
public class ConsoleEmailSender implements EmailSender {
@Override
public void send(String to, String message) {
System.out.println("DEV email to " + to + ": " + message);
}
}
Prod-Implementierung:
@Service
@Profile("prod")
public class SmtpEmailSender implements EmailSender {
@Override
public void send(String to, String message) {
// send via SMTP provider
}
}
Service:
@Service
public class RegistrationService {
private final EmailSender emailSender;
public RegistrationService(EmailSender emailSender) {
this.emailSender = emailSender;
}
}
Ist dev aktiv:
ConsoleEmailSender wird injiziert.
Ist prod aktiv:
SmtpEmailSender wird injiziert.
17. Was passiert, wenn kein Profile passt?
Beispiel:
@Service
@Profile("dev")
public class ConsoleEmailSender implements EmailSender {
}
@Service
@Profile("prod")
public class SmtpEmailSender implements EmailSender {
}
Service:
@Service
public class RegistrationService {
public RegistrationService(EmailSender emailSender) {
}
}
Ist kein Profile aktiv:
Keine EmailSender-Bean vorhanden.
Die App startet nicht.
Typischer Fehler:
No qualifying bean of type 'EmailSender' available
Lösungsoptionen:
- Ein Profile aktivieren.
- Eine Default-Bean bereitstellen.
@Profile("default")nutzen.@Profile("!prod")als Non-Production-Default nutzen.- Die Abhängigkeit optional machen, wenn sie wirklich optional ist.
18. Default Profile
Spring hat ein Default Profile namens:
default
Ist kein Profile aktiv, können Beans mit:
@Profile("default")
aktiv sein.
Beispiel:
@Service
@Profile("default")
public class DefaultEmailSender implements EmailSender {
}
Diese Bean ist nur aktiv, wenn kein anderes Profile aktiv ist.
Wichtig:
Das Default Profile wird genutzt, wenn kein explizites Profile aktiv ist.
19. @Profile("default") vs. @Profile("!prod")
@Profile("default")
Aktiv nur, wenn kein Profile explizit aktiv ist.
@Profile("default")
Nützlich als einfacher Fallback.
@Profile("!prod")
Aktiv, sobald prod nicht aktiv ist.
@Profile("!prod")
Aktiv in:
dev
test
local
docker
default
Nicht aktiv in:
prod
Merksatz:
defaultheißt: kein Profile ist aktiv.!prodheißt: jedes Profile außer prod.
20. Profile-spezifische Werte mit @ConfigurationProperties
YAML:
## application.yml
external-api:
base-url: https://api.default.com
timeout-seconds: 5
## application-prod.yml
external-api:
base-url: https://api.production.com
timeout-seconds: 20
Properties-Klasse:
@ConfigurationProperties(prefix = "external-api")
public record ExternalApiProperties(
String baseUrl,
int timeoutSeconds
) {
}
Ist prod aktiv:
baseUrl = https://api.production.com
timeoutSeconds = 20
Die Properties-Klasse braucht keine Profile-Logik.
Spring bindet die aktive Konfiguration automatisch.
21. Profile Groups
Spring Boot unterstützt Profile Groups.
Beispiel:
spring:
profiles:
group:
local:
- dev
- debug
- mock-email
Aktivierst du:
--spring.profiles.active=local
aktiviert Spring zusätzlich:
dev
debug
mock-email
Nützlich, wenn ein Profile eine Gruppe von Profiles aktivieren soll.
22. Profile Include
Du siehst auch Profile-Include-Konfiguration.
Beispiel:
spring:
profiles:
include: common
Damit wird ein weiteres Profile eingebunden.
Profile Groups sind für moderne Apps oft klarer.
Wichtig für die Prüfung:
Profiles können kombiniert oder gruppiert werden — Kernfragen in der Prüfung drehen sich meist um
@Profileund profile-spezifische Dateien.
23. Profiles und Tests
In Tests nutzt du:
@SpringBootTest
@ActiveProfiles("test")
class UserServiceTest {
}
Dann lädt Spring:
application.yml
application-test.yml
Und Beans mit:
@Profile("test")
können aktiv sein.
Beispiel:
@TestConfiguration
@Profile("test")
public class TestConfig {
}
24. Warum ein Test-Profile?
Ein Test-Profile kann nutzen:
Test-Datenbank
Fake Email Sender
Mock externe APIs
kurze Token-Ablaufzeit
deaktivierte Scheduled Jobs
schnellere Konfiguration
Beispiel:
## application-test.yml
spring:
datasource:
url: jdbc:h2:mem:testdb
app:
email-enabled: false
25. Profiles und Datenbank-Konfiguration
Beispiel Basisdatei:
## application.yml
spring:
jpa:
hibernate:
ddl-auto: validate
Dev-Datei:
## application-dev.yml
spring:
datasource:
url: jdbc:postgresql://localhost:5432/app_dev
username: postgres
password: postgres
Test-Datei:
## application-test.yml
spring:
datasource:
url: jdbc:h2:mem:testdb
Prod-Datei:
## application-prod.yml
spring:
datasource:
url: ${DB_URL}
username: ${DB_USERNAME}
password: ${DB_PASSWORD}
Gleicher Code.
Unterschiedliche Config.
26. Profiles und Logging
Dev:
## application-dev.yml
logging:
level:
org.springframework.security: DEBUG
de.klarsync: DEBUG
Prod:
## application-prod.yml
logging:
level:
org.springframework.security: WARN
de.klarsync: INFO
In der Entwicklung darf es ausführlicher sein.
In Production sollte es meist weniger laut sein.
27. Profiles und Feature Flags
Beispiel:
## application-dev.yml
feature:
new-dashboard: true
fake-email: true
## application-prod.yml
feature:
new-dashboard: false
fake-email: false
Properties:
@ConfigurationProperties(prefix = "feature")
public record FeatureProperties(
boolean newDashboard,
boolean fakeEmail
) {
}
Dann entscheiden Services ihr Verhalten anhand der Config.
28. Profiles vs. Feature Flags
Profiles sind für Konfiguration auf Umgebungsebene.
Feature Flags schalten Anwendungsfeatures ein oder aus.
Nutze Profiles für:
dev/test/prod-Umgebungsunterschiede
Nutze Feature Flags für:
ein Feature ein-/ausschalten
Erstelle nicht zu viele Profiles nur für kleine Feature-Schalter.
29. Profiles vs. Conditions
@Profile ist eine Art Condition basierend auf aktiven Profiles.
Spring Boot hat auch spezifischere Conditions:
@ConditionalOnProperty
@ConditionalOnMissingBean
@ConditionalOnClass
Beispiel:
@Bean
@ConditionalOnProperty(name = "feature.audit.enabled", havingValue = "true")
public AuditService auditService() {
return new AuditService();
}
Nutze @Profile für die Umgebung.
Nutze @ConditionalOnProperty für Feature-/Config-basierte Bedingungen.
30. Typischer Fehler: Profile in der Datei aktiv
Das kann gefährlich sein:
## application.yml
spring:
profiles:
active: prod
Warum?
Weil jede Umgebung, die diese Datei nutzt, mit prod starten kann.
Besser:
Aktives Profile per Environment Variable, Command Line, Docker, CI/CD oder IDE-Config setzen.
Für lokale Entwicklung ist es okay, die IDE auf dev zu konfigurieren.
31. Typischer Fehler: Dev und Prod gleichzeitig aktiv
Command:
java -jar app.jar --spring.profiles.active=dev,prod
Das kann verwirrendes Verhalten auslösen.
Beispiel:
@Profile("dev")
FakeEmailSender
und:
@Profile("prod")
RealEmailSender
Beide werden aktiv.
Implementieren beide EmailSender, wird die Injektion mehrdeutig.
Fix:
- inkompatible Profiles nicht zusammen nutzen
- Profile-Ausdrücke verwenden
@Primaryoder@Qualifiervorsichtig einsetzen- Profile-Kombinationen bewusst designen
32. Typischer Fehler: fehlende Default-Bean
Definierst du nur:
@Profile("dev")
FakeEmailSender
und:
@Profile("prod")
RealEmailSender
gibt es ohne aktives Profile keine EmailSender-Bean.
Soll die App lokal ohne explizites Profile laufen, füge hinzu:
@Profile("default")
oder:
@Profile("!prod")
— je nach Ziel.
33. Typischer Fehler: application-prod.yml lädt nicht automatisch
Diese Datei:
application-prod.yml
lädt nicht nur, weil sie existiert.
Sie lädt nur, wenn das prod-Profile aktiv ist.
Merksatz:
Profile-spezifische Dateien laden nur, wenn ihr Profile aktiv ist.
34. Typischer Fehler: Secrets in Profile-Dateien
Schlecht:
## application-prod.yml
spring:
datasource:
password: real-production-password
Besser:
## application-prod.yml
spring:
datasource:
password: ${DB_PASSWORD}
Dann setzen:
DB_PASSWORD=real-secret
Echte Secrets nicht committen.
35. Praxisfrage: Welche Config gewinnt?
Basis:
## application.yml
server:
port: 8080
Dev:
## application-dev.yml
server:
port: 8081
Command:
java -jar app.jar --spring.profiles.active=dev --server.port=9090
Endwert:
server.port = 9090
Warum?
Weil das Command-Line-Argument den Wert aus der Profile-Datei überschreibt.
Grundidee:
Externe Config mit höherer Priorität überschreibt Config mit niedrigerer Priorität.
36. Prüfungsfrage: Aktives Profile
Frage:
java -jar app.jar --spring.profiles.active=dev
Welche Dateien werden geladen?
Antwort:
Spring lädt die Basis-Konfiguration und die dev-spezifische Konfiguration:
application.yml
application-dev.yml
oder:
application.properties
application-dev.properties
— je nach Dateiformat.
37. Prüfungsfrage: @Profile
Frage:
@Service
@Profile("prod")
public class RealEmailSender implements EmailSender {
}
Wann wird diese Bean erzeugt?
Antwort:
Diese Bean wird nur erzeugt, wenn das prod-Profile aktiv ist.
38. Prüfungsfrage: Negatives Profile
Frage:
@Service
@Profile("!prod")
public class ConsoleEmailSender implements EmailSender {
}
Wann wird diese Bean erzeugt?
Antwort:
Diese Bean wird erzeugt, wenn das prod-Profile nicht aktiv ist.
39. Prüfungsfrage: Mehrere Profiles
Frage:
java -jar app.jar --spring.profiles.active=dev,docker
Ist das gültig?
Antwort:
Ja. Spring kann mehrere aktive Profiles haben. Sowohl dev als auch docker sind aktiv.
40. Prüfungsfrage: Kein passendes Profile
Frage:
@Service
@Profile("dev")
public class DevPaymentProvider implements PaymentProvider {
}
@Service
@Profile("prod")
public class ProdPaymentProvider implements PaymentProvider {
}
Kein Profile ist aktiv.
Was passiert, wenn eine andere Bean PaymentProvider braucht?
Antwort:
Es wird keine PaymentProvider-Bean erzeugt — Spring startet nicht und meldet einen Missing-Bean-Fehler.
41. Prüfungsfrage: Default Profile
Frage:
Was ist das default-Profile?
Antwort:
Das default-Profile ist aktiv, wenn kein anderes Profile explizit aktiv ist. Beans mit @Profile("default") können erzeugt werden, wenn kein Profile gesetzt ist.
42. Prüfungsfrage: default vs. !prod
Frage:
Was ist der Unterschied zwischen @Profile("default") und @Profile("!prod")?
Antwort:
@Profile("default") ist nur aktiv, wenn kein Profile explizit aktiv ist. @Profile("!prod") ist aktiv, sobald das prod-Profile nicht aktiv ist — also auch bei dev, test, local oder im Default-Modus.
43. Prüfungsfrage: application-prod.yml
Frage:
Lädt application-prod.yml automatisch, nur weil die Datei existiert?
Antwort:
Nein. Sie lädt nur, wenn das prod-Profile aktiv ist.
44. Prüfungsfrage: Test-Profile
Frage:
Wie aktivierst du das test-Profile in einem Spring-Boot-Test?
Antwort:
Nutze:
@ActiveProfiles("test")
Beispiel:
@SpringBootTest
@ActiveProfiles("test")
class MyTest {
}
45. Prüfungsfrage: Profiles vs. Properties
Frage:
Solltest du Profiles oder Feature Flags nutzen, um ein kleines Feature einzuschalten?
Antwort:
Meist ein Feature Flag oder eine Property — kein neues Profile. Profiles eignen sich besser für Konfiguration auf Umgebungsebene wie dev, test, prod oder docker.
46. Interview-Antwort
Frage:
Was sind Spring Profiles?
Gute Antwort:
Spring Profiles erlauben uns, für verschiedene Umgebungen unterschiedliche Beans und Konfiguration zu definieren — z. B. dev, test und prod. Ein Profile kann profile-spezifische Konfigurationsdateien wie application-dev.yml und Beans mit @Profile("dev") aktivieren. So läuft derselbe Anwendungscode mit unterschiedlichen umgebungsspezifischen Einstellungen.
47. Interview-Antwort
Frage:
Wie funktionieren profile-spezifische Konfigurationsdateien?
Gute Antwort:
Spring Boot lädt immer die Basis-Konfigurationsdatei, z. B. application.yml. Ist ein Profile aktiv — etwa dev — lädt Spring zusätzlich application-dev.yml. Werte aus der profile-spezifischen Datei können Werte aus der Basisdatei überschreiben. Das Profile aktivierst du mit spring.profiles.active, einer Environment Variable, einem Command-Line-Argument oder @ActiveProfiles in Tests.
48. Interview-Antwort
Frage:
Was macht
@Profile?
Gute Antwort:
@Profile steuert, ob eine Bean oder Configuration-Klasse für ein bestimmtes Profile aktiv ist. @Profile("dev") heißt: Die Bean wird nur erzeugt, wenn das dev-Profile aktiv ist. Du kannst es auf Klassen, Configuration-Klassen oder @Bean-Methoden setzen. Nützlich, wenn verschiedene Umgebungen unterschiedliche Bean-Implementierungen brauchen.
49. Interview-Antwort
Frage:
Wie aktivierst du ein Profile in Spring Boot?
Gute Antwort:
Ein Profile kannst du auf mehrere Arten aktivieren — z. B. per Command-Line-Argument --spring.profiles.active=prod, per Environment Variable SPRING_PROFILES_ACTIVE=prod, in der IDE Run Configuration oder in Tests mit @ActiveProfiles("test"). In Production aktivierst du Profiles meist über Umgebungs- oder Deployment-Konfiguration statt sie in application.yml fest zu codieren.
50. Interview-Antwort
Frage:
Welche Probleme können Profiles verursachen?
Gute Antwort:
Profiles können Missing-Bean-Fehler verursachen, wenn kein aktives Profile zur benötigten Bean passt. Sie können auch Mehrdeutigkeit erzeugen, wenn mehrere Profiles aktiv sind und mehrere Beans desselben Typs erzeugt werden. Ein häufiges Problem: Man erwartet, dass application-prod.yml automatisch lädt, obwohl das prod-Profile nicht aktiv ist. Profile-Nutzung klar designen und inkompatible Profiles nicht gleichzeitig aktivieren.
51. Kleines Code-Übungsbeispiel
Erstelle dieses Interface:
public interface StorageService {
void store(String fileName);
}
Dev-Implementierung:
@Service
@Profile("dev")
public class LocalStorageService implements StorageService {
@Override
public void store(String fileName) {
System.out.println("Storing locally: " + fileName);
}
}
Prod-Implementierung:
@Service
@Profile("prod")
public class S3StorageService implements StorageService {
@Override
public void store(String fileName) {
System.out.println("Uploading to S3: " + fileName);
}
}
Nutzung:
@Service
public class DocumentService {
private final StorageService storageService;
public DocumentService(StorageService storageService) {
this.storageService = storageService;
}
}
Fragen:
- Welche Bean wird erzeugt, wenn
devaktiv ist? - Welche Bean wird erzeugt, wenn
prodaktiv ist? - Was passiert, wenn kein Profile aktiv ist?
Antworten:
LocalStorageServiceS3StorageService- Keine
StorageService-Bean vorhanden — die App startet ggf. nicht, außer es gibt eine Default-Bean.
52. Kleines Bug-Übungsbeispiel
Problem:
@Service
@Profile("dev")
public class FakeEmailSender implements EmailSender {
}
@Service
@Profile("prod")
public class RealEmailSender implements EmailSender {
}
Command:
java -jar app.jar --spring.profiles.active=dev,prod
Frage:
Was ist das Problem?
Antwort:
Sowohl FakeEmailSender als auch RealEmailSender werden aktiv. Braucht eine andere Bean EmailSender, findet Spring zwei Kandidaten und schlägt ggf. mit einem Ambiguity-Fehler fehl — außer eine Bean ist @Primary, wird per @Qualifier gewählt oder die Profiles sind bewusst gegenseitig ausschließend designed.
Übungsfragen
Frage 1
Was ist ein Spring Profile?
Antwort:
Ein Spring Profile ist ein benannter Umgebungsmodus, der steuert, welche Konfiguration und welche Beans aktiv sind.
Frage 2
Warum brauchen wir Profiles?
Antwort:
Profiles brauchen wir, weil verschiedene Umgebungen — lokal, Test, Production — unterschiedliche Konfiguration und manchmal unterschiedliche Bean-Implementierungen brauchen.
Frage 3
Nenne drei häufige Profiles.
Antwort:
Häufige Profiles sind:
dev
test
prod
Weitere übliche:
local
docker
ci
staging
Frage 4
Welche Datei wird für das dev-Profile geladen?
Antwort:
Für das dev-Profile lädt Spring Boot:
application.yml
application-dev.yml
oder die entsprechenden .properties-Dateien.
Frage 5
Lädt application-prod.yml automatisch, nur weil sie existiert?
Antwort:
Nein. application-prod.yml lädt nur, wenn das prod-Profile aktiv ist.
Frage 6
Wie aktivierst du das prod-Profile über die Command Line?
Antwort:
Nutze:
java -jar app.jar --spring.profiles.active=prod
Frage 7
Wie aktivierst du das prod-Profile mit einer Environment Variable?
Antwort:
Nutze:
SPRING_PROFILES_ACTIVE=prod java -jar app.jar
Frage 8
Wie aktivierst du das test-Profile in einem Test?
Antwort:
Nutze:
@ActiveProfiles("test")
Beispiel:
@SpringBootTest
@ActiveProfiles("test")
class MyTest {
}
Frage 9
Was bedeutet @Profile("dev")?
Antwort:
@Profile("dev") heißt: Die Bean oder Configuration ist nur aktiv, wenn das dev-Profile aktiv ist.
Frage 10
Kann @Profile auf @Bean-Methoden gesetzt werden?
Antwort:
Ja. @Profile kann auf @Bean-Methoden gesetzt werden.
Frage 11
Kann @Profile auf eine ganze Configuration-Klasse gesetzt werden?
Antwort:
Ja. @Profile kann auf eine ganze Configuration-Klasse gesetzt werden. Dann sind alle Beans in dieser Klasse nur aktiv, wenn das Profile passt.
Frage 12
Können mehrere Profiles gleichzeitig aktiv sein?
Antwort:
Ja. Mehrere Profiles können gleichzeitig aktiv sein — z. B. dev,docker.
Frage 13
Was bedeutet @Profile("!prod")?
Antwort:
@Profile("!prod") heißt: Die Bean ist aktiv, wenn das prod-Profile nicht aktiv ist.
Frage 14
Was bedeutet @Profile("dev | test")?
Antwort:
@Profile("dev | test") heißt: Die Bean ist aktiv, wenn dev oder test aktiv ist.
Frage 15
Was bedeutet @Profile("dev & docker")?
Antwort:
@Profile("dev & docker") heißt: Die Bean ist nur aktiv, wenn sowohl dev als auch docker aktiv sind.
Frage 16
Was ist das Default Profile?
Antwort:
Das Default Profile ist aktiv, wenn kein anderes Profile explizit aktiv ist.
Frage 17
Was ist der Unterschied zwischen @Profile("default") und @Profile("!prod")?
Antwort:
@Profile("default") ist nur aktiv, wenn kein explizites Profile aktiv ist. @Profile("!prod") ist aktiv, sobald das prod-Profile nicht aktiv ist — also auch bei dev, test, local oder im Default-Modus.
Frage 18
Was passiert, wenn keine profile-spezifische Bean zu einer benötigten Abhängigkeit passt?
Antwort:
Gibt es keine passende Bean für eine benötigte Abhängigkeit, startet Spring meist nicht und meldet einen Missing-Bean-Fehler.
Frage 19
Was passiert, wenn dev und prod gleichzeitig aktiv sind und beide dieselbe Interface-Bean erzeugen?
Antwort:
Beide Beans können aktiv werden. Implementieren beide dasselbe Interface und braucht eine andere Bean dieses Interface, schlägt Spring ggf. mit einem Ambiguity-Fehler fehl — außer die Mehrdeutigkeit ist aufgelöst.
Frage 20
Was ist der Unterschied zwischen Profiles und Feature Flags?
Antwort:
Profiles sind für Konfiguration auf Umgebungsebene wie dev, test und prod. Feature Flags schalten bestimmte Anwendungsfeatures ein oder aus.
Merksätze zum Mitnehmen
- Ein Spring Profile steuert, welche Konfiguration und welche Beans aktiv sind.
- Häufige Profiles sind
dev,testundprod. application.ymlist die Basis-Konfiguration.application-dev.ymllädt nur, wenndevaktiv ist.- Profile-spezifische Dateien überschreiben die Basis-Konfiguration.
@Profile("dev")erzeugt eine Bean nur, wenndevaktiv ist.@Profile("!prod")erzeugt eine Bean, wennprodnicht aktiv ist.- Mehrere Profiles können gleichzeitig aktiv sein.
@Profile("default")ist nur aktiv, wenn kein explizites Profile aktiv ist.- Profiles aktivierst du per Command-Line-Argument, Environment Variable, IDE-Config oder
@ActiveProfilesin Tests. - Echte Production-Secrets nicht in Profile-Dateien committen.
- Inkompatible Profiles nicht gleichzeitig aktivieren.
- Profiles sind für Umgebungen.
- Feature Flags sind für Anwendungsfeatures.