01Dependency InjectionService Locator und manuelle Registrierung → Constructor Injection mit SpringVergleich öffnen
Service Locator und manuelle Registrierung
Der Aufrufer holt die Abhängigkeit zur Laufzeit aus einer globalen Registry.
Constructor Injection mit Spring
Der Container übergibt den fachlichen Port sichtbar über den Konstruktor.
Fachlich korrekter Direktvergleich
| Dimension | Legacy | Modern |
|---|---|---|
| Mechanismus | Der Aufrufer holt die Abhängigkeit zur Laufzeit aus einer globalen Registry. | Der Container übergibt den fachlichen Port sichtbar über den Konstruktor. |
| Kernunterschied | Versteckte Laufzeitauflösung wird durch eine explizite, unveränderliche Abhängigkeit ersetzt. | |
| Patterns | Service Locator | Port, Constructor Injection |
Code mit gleicher fachlicher Rolle
Verdrahtung des gleichen Aufrufs
package at.aydin.lab.di.legacy;
public final class DiLegacyApplication {
private DiLegacyApplication() {
}
public static void main(String[] args) {
ServiceRegistry.register(GreetingService.class, new DefaultGreetingService());
GreetingService service = ServiceRegistry.resolve(GreetingService.class);
System.out.println(service.greet("Aydin"));
}
}package at.aydin.lab.di.modern;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;
@Component
public class GreetingRunner implements CommandLineRunner {
private final GreetingPort greetingPort;
// Design Pattern: Constructor Injection
// Zweck: Abhängigkeiten sind sichtbar, unveränderlich und leicht testbar.
public GreetingRunner(GreetingPort greetingPort) {
this.greetingPort = greetingPort;
}
@Override
public void run(String ... args) {
System.out.println(greetingPort.greet("Aydin"));
}
}Gleiche fachliche Implementierung
package at.aydin.lab.di.legacy;
public final class DefaultGreetingService implements GreetingService {
@Override
public String greet(String name) {
return "Willkommen, " + name + "!";
}
}package at.aydin.lab.di.modern;
import org.springframework.stereotype.Service;
@Service
public class GermanGreetingService implements GreetingPort {
@Override
public String greet(String name) {
return "Willkommen, " + name + "!";
}
}Empfohlene Migration
- Verhalten sichern: denselben Greeting-Service auflösen und ausführen mit denselben Eingaben und erwarteten Ausgaben testen.
- Legacy-Grenze isolieren: Service Locator und manuelle Registrierung hinter einem kleinen Vertrag oder Adapter kapseln.
- Modernes Gegenstück einführen: Constructor Injection mit Spring implementieren, ohne den Fachfall zu ändern.
- Parity prüfen: Legacy- und Modern-Modul gegen dieselbe Fachfall-Matrix ausführen.
- Technische Unterschiede separat testen: Container, Protokoll, Persistenz oder Security nicht mit Unit-Tests vortäuschen.