Zum Hauptinhalt springen

Woche 2, Tag 3 — Spring Profiles: dev, test, prod und @Profile

Ziel

Heute verstehst du Spring Profiles.

Die Kernfragen:

  1. Was ist ein Spring Profile?
  2. Warum brauchen wir Profiles?
  3. Wie funktionieren application-dev.yml, application-test.yml und application-prod.yml?
  4. Wie aktivierst du ein Profile?
  5. Was macht @Profile?
  6. Kannst du mehrere aktive Profiles haben?
  7. Was bedeutet @Profile("!prod")?
  8. Wie wirken Profiles auf Beans?
  9. Wie wirken Profiles auf Konfigurationsdateien?
  10. 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.
  • @Value injiziert einen einzelnen Wert.
  • @ConfigurationProperties bindet 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.yml ist die Basis-Config. application-dev.yml überschreibt sie, wenn dev aktiv 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

AusdruckBedeutung
devaktiv, wenn dev aktiv ist
prodaktiv, wenn prod aktiv ist
!prodaktiv, wenn prod nicht aktiv ist
`devtest`aktiv, wenn dev oder test aktiv ist
dev & dockeraktiv, 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:

  1. Ein Profile aktivieren.
  2. Eine Default-Bean bereitstellen.
  3. @Profile("default") nutzen.
  4. @Profile("!prod") als Non-Production-Default nutzen.
  5. 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:

default heißt: kein Profile ist aktiv. !prod heiß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 @Profile und 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
  • @Primary oder @Qualifier vorsichtig 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:

  1. Welche Bean wird erzeugt, wenn dev aktiv ist?
  2. Welche Bean wird erzeugt, wenn prod aktiv ist?
  3. Was passiert, wenn kein Profile aktiv ist?

Antworten:

  1. LocalStorageService
  2. S3StorageService
  3. 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, test und prod.
  • application.yml ist die Basis-Konfiguration.
  • application-dev.yml lädt nur, wenn dev aktiv ist.
  • Profile-spezifische Dateien überschreiben die Basis-Konfiguration.
  • @Profile("dev") erzeugt eine Bean nur, wenn dev aktiv ist.
  • @Profile("!prod") erzeugt eine Bean, wenn prod nicht 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 @ActiveProfiles in 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.