Migration Deep Dive für 01 · Dependency Injection öffnen →
⌂ ÜbersichtAlle Vergleiche
Modul 01 · 100 % Codeabdeckung

Dependency Injection

Vollständiger Legacy-Modern-Vergleich aller Java-Klassen, Tests, Maven-POMs und relevanten Ressourcen dieses Moduls. Jede Datei ist genau einmal einer fachlich passenden Vergleichsgruppe zugeordnet.

6Legacy-Dateien
6Modern-Dateien
92 → 97Codezeilen
13/13vollständig erfasst

Fachliche Einordnung

Legacy

Service Locator und manuelle Registrierung

Der Aufrufer holt die Abhängigkeit zur Laufzeit aus einer globalen Registry.

Modern

Constructor Injection mit Spring

Der Container übergibt den fachlichen Port sichtbar über den Konstruktor.

Vergleichsfokus: Alle Dateien werden nach technischer Rolle und fachlicher Verantwortung gruppiert.
Wichtige Abgrenzung: One-to-many-Änderungen werden als Gruppe dargestellt; eine künstliche 1:1-Zuordnung wird vermieden.

Vollständige Abdeckungsmatrix

Die Ähnlichkeit ist eine technische Orientierung auf normalisiertem Quelltext. Sie ersetzt keine fachliche Bewertung.

VergleichsgruppeLegacy-DateienModern-DateienLegacy-ZeilenModern-ZeilenÄhnlichkeit
Build-Konfiguration11313852%
Bootstrap und Ausführung12123025%
Service-Vertrag und Implementierung22131863%
Auflösung und Test21361135%

Gemeinsame Modulstruktur

Das Pair-POM bindet die Legacy- und Modern-Submodule zusammen und gehört deshalb ebenfalls zur vollständigen Codeabdeckung.

Gemeinsam · 19 Zeilenpom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>at.aydin.academy</groupId>
        <artifactId>java-modernization-deep-dive</artifactId>
        <version>1.0.0</version>
        <relativePath>../../pom.xml</relativePath>
    </parent>
    <artifactId>01dependencyinjection-pair</artifactId>
    <packaging>pom</packaging>
    <name>Dependency Injection: Legacy und Modern</name>
    <modules>
        <module>legacy</module>
        <module>modern</module>
    </modules>
</project>

Alle semantischen Codevergleiche

01Build-KonfigurationDirektvergleich · Legacy 31 / Modern 38 Zeilen · Ähnlichkeit 52%

Abhängigkeiten und Compiler-/Testkonfiguration werden direkt verglichen.

Legacy-DateienModern-DateienEinordnung
pom.xmlpom.xmlDirektvergleich
Semantische Ähnlichkeit: 52%

Legacy

Legacy · 31 Zeilenlegacy/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>at.aydin.academy</groupId>
        <artifactId>01dependencyinjection-pair</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>di-legacy</artifactId>
    <packaging>jar</packaging>
    <name>DI Legacy</name>
    <dependencies>
        <dependency>
            <groupId>org.junit.jupiter</groupId>
            <artifactId>junit-jupiter</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>

        </plugins>
    </build>
</project>

Modern

Modern · 38 Zeilenmodern/pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>at.aydin.academy</groupId>
        <artifactId>01dependencyinjection-pair</artifactId>
        <version>1.0.0</version>
        <relativePath>../pom.xml</relativePath>
    </parent>
    <artifactId>di-modern</artifactId>
    <packaging>jar</packaging>
    <name>DI Modern</name>
    <dependencies>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
        </dependency>
    </dependencies>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
            </plugin>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
02Bootstrap und AusführungDirektvergleich · Legacy 12 / Modern 30 Zeilen · Ähnlichkeit 25%

Manueller Start wird durch Spring Boot und einen injizierten Runner ersetzt.

Legacy-DateienModern-DateienEinordnung
DiLegacyApplication.javaDiModernApplication.java
GreetingRunner.java
Direktvergleich
Semantische Ähnlichkeit: 25%

Legacy

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"));
    }
}

Modern

package at.aydin.lab.di.modern;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class DiModernApplication {
    public static void main(String[] args) {
        SpringApplication.run(DiModernApplication.class, args);
    }
}
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"));
    }
}
03Service-Vertrag und ImplementierungDirektvergleich · Legacy 13 / Modern 18 Zeilen · Ähnlichkeit 63%

Konkrete Abhängigkeit wird in Port und injizierbare Implementierung getrennt.

Legacy-DateienModern-DateienEinordnung
GreetingService.java
DefaultGreetingService.java
GreetingPort.java
GermanGreetingService.java
Direktvergleich
Semantische Ähnlichkeit: 63%

Legacy

Modern

package at.aydin.lab.di.modern;

// Design Pattern: Port (Hexagonal Architecture)
// Zweck: Die Anwendung hängt von einem fachlichen Vertrag statt einer konkreten Implementierung ab.
public interface GreetingPort {
    String greet(String name);
}
04Auflösung und TestDirektvergleich · Legacy 36 / Modern 11 Zeilen · Ähnlichkeit 35%

Die globale Registry entfällt; Verhalten wird direkt am Bean-Vertrag getestet.

Legacy-DateienModern-DateienEinordnung
ServiceRegistry.java
ServiceRegistryTest.java
GermanGreetingServiceTest.javaDirektvergleich
Semantische Ähnlichkeit: 35%

Legacy

package at.aydin.lab.di.legacy;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

// Design Pattern: Service Locator
// Zweck: Zentrale, manuelle Auflösung von Abhängigkeiten in Legacy-Anwendungen.
public final class ServiceRegistry {
    private static final Map<Class<?>, Object> SERVICES = new ConcurrentHashMap<>();
    private ServiceRegistry() {
    }

    public static <T> void register(Class<T> type, T implementation) {
        SERVICES.put(type, implementation);
    }

    public static <T> T resolve(Class<T> type) {
        Object service = SERVICES.get(type);
        if (service == null) {
            throw new IllegalStateException("Kein Service registriert: " + type.getName());
        }
        return type.cast(service);
    }
}
package at.aydin.lab.di.legacy;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class ServiceRegistryTest {
    @Test
    void resolvesRegisteredService() {
        ServiceRegistry.register(GreetingService.class, new DefaultGreetingService());
        assertEquals("Willkommen, Test!", ServiceRegistry.resolve(GreetingService.class).greet("Test"));
    }
}

Modern

package at.aydin.lab.di.modern;

import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;

class GermanGreetingServiceTest {
    @Test
    void greetsUser() {
        assertEquals("Willkommen, Test!", new GermanGreetingService().greet("Test"));
    }
}
⌂ Cockpit