Читать книгу Spring Boot - Mark Heckler - Страница 52

Ein bisschen Nachpolieren

Оглавление

Wie überall gibt es auch hier Bereiche, die noch etwas zusätzliche Aufmerksamkeit vertragen können. Ich werde mich allerdings auf zwei beschränken: das Extrahieren der Anfangsbelegung der Beispieldaten in eine separate Komponente und ein Umsortieren der Bedingungsoperatoren aus Gründen der Klarheit.

Im vorigen Kapitel habe ich die Liste der Kaffees mit einigen Anfangswerten in der Klasse RestApiDemoController gefüllt. Diese Struktur habe ich auch in diesem Kapitel – bis jetzt – beibehalten, nachdem ich das Ganze in eine Datenbank mit Repository-Zugriff umgewandelt hatte. Besser ist es jedoch, diese Funktionalität in eine separate Komponente auszulagern, die schnell und einfach aktiviert oder deaktiviert werden kann.

Es gibt viele Möglichkeiten, Code automatisch beim Start einer Anwendung auszuführen. Sie könnten etwa einen CommandLineRunner oder ApplicationRunner einsetzen und ein Lambda festlegen, um das gewünschte Ziel zu erreichen: in diesem Fall das Erzeugen und Speichern von Beispieldaten. Ich jedoch benutze dafür lieber eine @Component-Klasse und eine @PostConstruct-Methode. Das hat folgende Gründe:

 Wenn die Bean-erzeugenden Methoden CommandLineRunner und Application Runner eine Repository-Bean injizieren (automatisch verdrahten), scheitern Unit-Tests, die die Repository-Bean innerhalb des Tests »mocken« (was typischerweise der Fall ist).

 Falls Sie die Repository-Bean in dem Test mocken oder die Anwendung ausführen wollen, ohne Beispieldaten zu erzeugen, lässt sich die eigentliche datenerzeugende Bean schnell und einfach deaktivieren, indem Sie deren @Component-Annotation auskommentieren.

Ich empfehle das Anlegen einer DataLoader-Klasse ähnlich derjenigen, die Sie im folgenden Codeblock sehen. Wenn Sie die Logik zum Erzeugen der Beispieldaten in die loadData()-Methode der DataLoader-Klasse auslagern und sie mit @PostContruct annotieren, führen Sie RestApiDemoController wieder seiner eigentlichen Aufgabe zu, nämlich dem Bereitstellen eines externen API. Der DataLoader wiederum wird für seinen gedachten (und offensichtlichen) Zweck verantwortlich gemacht:

@Component

class DataLoader {

private final CoffeeRepository coffeeRepository;

public DataLoader(CoffeeRepository coffeeRepository) {

this.coffeeRepository = coffeeRepository;

}

@PostConstruct

private void loadData() {

coffeeRepository.saveAll(List.of(

new Coffee("Café Cereza"),

new Coffee("Café Ganador"),

new Coffee("Café Lareño"),

new Coffee("Café Três Pontas")

));

}

}

Die andere Verfeinerung ist eine zugegebenermaßen kleine Änderung der booleschen Bedingung des Dreifachoperators in der Methode putCoffee(). Nachdem die Methode so umgebaut wurde, dass sie ein Repository benutzt, gibt es keinen zwingenden Grund mehr, zuerst die negative Bedingung auszuwerten. Durch das Entfernen des Not-Operators (!) aus der Bedingung wird das Ganze etwas klarer; es ist nun natürlich noch erforderlich, die True- und False-Werte des Dreifachoperators zu vertauschen, um wieder auf die ursprünglichen Ergebnisse zu kommen. Der folgende Code spiegelt das wider:

@PutMapping("/{id}")

ResponseEntity<Coffee> putCoffee(@PathVariable String id,

@RequestBody Coffee coffee) {

return (coffeeRepository.existsById(id))

? new ResponseEntity<>(coffeeRepository.save(coffee),

HttpStatus.OK)

: new ResponseEntity<>(coffeeRepository.save(coffee),

HttpStatus.CREATED);

}

Hinweis zum Code-Checkout Wenn Sie den kompletten Code für dieses Kapitel haben wollen, checken Sie den Zweig chapter4end aus dem Code-Repository aus.
Spring Boot

Подняться наверх