RU | EN | DE

1. IoC (Inversion of Control — Umkehrung der Kontrolle)

Idee:
Du erstellst Objekte nicht manuell (new), sondern ein Container (Spring) verwaltet ihre Erstellung und Verknüpfung.

👉 In der typischen Java:

class Car {
    private Engine engine = new Engine(); // starre Kopplung
}

👉 In Spring (durch DI):

@Component
class Engine {}
@Component
class Car {
    private final Engine engine;
    @Autowired
    Car(Engine engine) { this.engine = engine; }
}

⚡ Jetzt erstellt der Spring-Container Engine und Car.

2. DI (Dependency Injection — Abhängigkeitsinjektion)

Arten der DI:

  1. Über den Konstruktor (bessere Methode)
@Component
class UserService {
    private final UserRepository repo;
    @Autowired
    UserService(UserRepository repo) { this.repo = repo; }
}
  1. Über ein Feld (Anti-Pattern, wird aber gefunden)
@Component
class UserService {
    @Autowired
    private UserRepository repo;
}
  1. Über einen Setter
@Component
class UserService {
    private UserRepository repo;
    @Autowired
    public void setRepo(UserRepository repo) {
        this.repo = repo;
    }
}

3. Beans (Behälter)

Bean = Objekt, das von Spring verwaltet wird.

👉 Erstellung eines Beans:

@Component
class MyService {}

👉 Alternative (Java Config):

@Configuration
class AppConfig {
    @Bean
    public MyService myService() {
        return new MyService();
    }
}

4. ApplicationContext

Spring speichert alle Beans im ApplicationContext (Container). Beispiel für einen Start ohne Spring Boot:

AnnotationConfigApplicationContext ctx =
        new AnnotationConfigApplicationContext(AppConfig.class);
MyService service = ctx.getBean(MyService.class);
service.doWork();

In Spring Boot geschieht dies automatisch.

5. Lebenszyklus eines Beans

  1. Objekt erstellen
  2. Abhängigkeiten injizieren
  3. @PostConstruct aufrufen
  4. Nutzung
  5. Zerstörung (PreDestroy aufrufen)
@Component
class MyBean {
    @PostConstruct
    public void init() {
        System.out.println("Bean initialisiert");
    }
       
    @PreDestroy
    public void cleanup() {
        System.out.println("Bean zerstört");
    }
}

6. Scope (Lebenszyklus von Beans)

  • singleton (Standard) → ein Objekt pro Anwendung
  • prototype → ein neues Objekt bei jeder Anfrage
  • request (Web) → ein Objekt pro HTTP-Anfrage
  • session (Web) → ein Objekt pro Sitzung
@Component
@Scope("prototype")
class PrototypeBean {}

7. Spring Core Annotationen

AnnotationFunktion
@ComponentBean-Komponente
@ServiceBusiness-Logik
@RepositoryDAO-Schicht (automatisch @Transactional)
@ControllerMVC-Controller
@RestControllerController mit @ResponseBody
@ConfigurationKonfigurationsklasse
@BeanBean innerhalb von @Configuration
@AutowiredAbhängigkeitsinjektion
@QualifierBean-Spezifizierung, wenn mehrere vorhanden sind
@ValueWert aus application.properties injizieren

8. Konfigurationen (Java, XML, Annotationen)

Heute wird fast immer Java Config und Annotationen verwendet.

@Configuration
class MyConfig {
    @Bean
    public Engine engine() {
        return new Engine();
    }
}

9. Profile (verschiedene Umgebungen)

application.properties:

spring.profiles.active=dev

Definition eines Beans für ein bestimmtes Profil:

@Component
@Profile("dev")
class DevDatabaseConfig {}

10. Best Practices

  • ✅ Verwende Dependency Injection über den Konstruktor → einfacher zu testen, weniger Probleme mit null.
  • ✅ Erstelle Klassen mit @Service → für Business-Logik, @Repository → für die Arbeit mit der Datenbank.
  • ✅ Verwende @Autowired nur in Konstruktoren (nicht in Feldern).
  • ✅ Überwache den Scope → Standardmäßig ist singleton besser.
  • ✅ Verwende @Configuration und @Bean für komplexe Abhängigkeiten.