Mit AI Zeit sparen in der Entwicklung: Detailliert mit Beispielen
1. Überblick
Diese Anleitung beantwortet eine praktische Frage: Wie nutzt du AI (konkret LLM wie GPT, Claude), um Zeit bei deiner täglichen Programmierarbeit zu sparen, ohne blind Code zu kopieren? Du wirst sehen, wie du LLM in Spring Boot-Anwendungen mit Spring AI integrierst, wie du AI zum Generieren von Tests, Javadoc und anderen Dokumentationen nutzt, und welche Fallstricke du vermeiden solltest.
Nach dieser Anleitung kannst du einen ChatClient schreiben, der LLM in Spring Boot aufruft, weißt, wie du Prompts für verschiedene Aufgaben formulierst (Code generieren, Review, Tests schreiben), und kennst die Grenzen von AI – wann sie dir wirklich hilft und wann sie dich nur verlangsamt.
2. Wo AI Zeit in der Entwicklung spart
Nicht überall ist AI schneller als wenn du es selbst machst. Drei Gruppen von Aufgaben, wo AI sich wirklich lohnt:
- Repetitive Arbeit mit klarem Muster: DTOs aus Entities generieren, Getter/Setter generieren (auch wenn die IDE das kann), Boilerplate-Test-Fälle generieren.
- Aufgaben, die schnelle Zusammenfassung brauchen: lange Stacktraces lesen, PRs zusammenfassen, Legacy-Code ohne Kommentare erklären.
- Aufgaben, bei denen du einen schnellen ersten Entwurf brauchst: Javadoc schreiben, README verfassen, komplexe SQL-Queries formulieren, die du dann anpasst.
Im Gegenteil: AI spart keine Zeit, wenn: du das Problem nicht klar verstanden hast (vage Prompts = vage Ergebnisse), die Geschäftslogik komplex und unternehmensspezifisch ist, oder wenn der Code hohe Sicherheits-/Finanzgenauigkeit braucht, die du nicht gründlich überprüfst.
Hinweis: Wenn AI schnell Code erzeugt, aber Review langsam ist, sinkt die Gesamtzeit nicht – manchmal steigt sie sogar, weil du Code debuggen musst, der „richtig aussieht, aber falsche Logik hat”.
3. LLM in Spring Boot mit Spring AI integrieren
Statt REST APIs manuell mit RestTemplate aufzurufen, nutzt du Spring AI, um einen bequemen ChatClient zu haben.
<dependency>
<groupId>org.springframework.ai</groupId>
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
<version>1.0.0</version>
</dependency>
Deklariere den API-Schlüssel in application.properties:
spring.ai.openai.api-key=${OPENAI_API_KEY}
spring.ai.openai.chat.options.model=gpt-4o-mini
Erstelle einen Service, der ChatClient wrappet:
@Service
public class CodeAssistantService {
private final ChatClient chatClient;
public CodeAssistantService(ChatClient.Builder builder) {
this.chatClient = builder.build();
}
public String explainStackTrace(String stackTrace) {
String prompt = """
Du bist ein erfahrener Java-Ingenieur. Erkläre kurz die Ursache
des folgenden Stacktraces und schlage eine Lösung vor:
%s
""".formatted(stackTrace);
return chatClient.prompt()
.user(prompt)
.call()
.content();
}
}
ChatClient.Builderwird von Spring Boot durch den obigen Starter automatisch konfiguriert, du musst es nur injizieren.prompt().user(...).call().content()sendet den Prompt und gibt direkt den Antworttext zurück, ohne manuelles JSON-Parsing.- Die
explainStackTrace-Methode nimmt eine lange Stacktrace und gibt eine kurze Erklärung zurück – das spart dir 5–10 Minuten Logs lesen jedes Mal, wenn du einen unerwarteten Fehler debuggst.
Nutze es in einem Controller:
@RestController
@RequestMapping("/api/assist")
public class CodeAssistantController {
private final CodeAssistantService assistantService;
public CodeAssistantController(CodeAssistantService assistantService) {
this.assistantService = assistantService;
}
@PostMapping("/explain")
public String explain(@RequestBody String stackTrace) {
return assistantService.explainStackTrace(stackTrace);
}
}
Das Ergebnis eines POST /api/assist/explain-Aufrufs mit einer NullPointerException-Stacktrace gibt etwa folgenden erklärenden Text zurück:
Der NullPointerException tritt auf, weil die Variable `customer` nicht
initialisiert wurde, bevor `customer.getEmail()` aufgerufen wird.
Überprüfe OrderService – das Repository könnte null zurückgeben, wenn
kein Datensatz gefunden wird. Nutze Optional oder prüfe null, bevor du
auf Eigenschaften zugreifst.
4. AI zum automatischen Generieren von Unit Tests – konkretes Beispiel
Eine der zeitaufwändigsten Aufgaben ist das Schreiben von Test-Fällen für jeden Code-Weg. Angenommen, du hast die Klasse DiscountCalculator:
public class DiscountCalculator {
public BigDecimal calculate(BigDecimal orderAmount, CustomerTier tier) {
if (orderAmount.compareTo(BigDecimal.ZERO) <= 0) {
throw new IllegalArgumentException("Order amount must be positive");
}
BigDecimal rate = switch (tier) {
case GOLD -> new BigDecimal("0.15");
case SILVER -> new BigDecimal("0.10");
case BASIC -> new BigDecimal("0.05");
};
return orderAmount.multiply(rate).setScale(2, RoundingMode.HALF_UP);
}
}
Ein Beispiel-Prompt, um das LLM zur Generierung von Tests zu bitten (du kopierst die Klasse in den Prompt):
Schreibe Unit Tests mit JUnit 5 + AssertJ für die Klasse DiscountCalculator.
Decke folgende Fälle ab: GOLD, SILVER, BASIC und der Fall orderAmount <= 0,
der IllegalArgumentException werfen sollte. Nutze @ParameterizedTest, wo sinnvoll.
AI gibt normalerweise einen brauchbaren Entwurf zurück, du passt ihn dann an den Stil deines Teams an:
class DiscountCalculatorTest {
private final DiscountCalculator calculator = new DiscountCalculator();
@ParameterizedTest
@CsvSource({
"GOLD, 100, 15.00",
"SILVER, 100, 10.00",
"BASIC, 100, 5.00"
})
void shouldCalculateDiscountByTier(CustomerTier tier, String amount, String expected) {
BigDecimal result = calculator.calculate(new BigDecimal(amount), tier);
assertThat(result).isEqualByComparingTo(new BigDecimal(expected));
}
@Test
void shouldThrowWhenOrderAmountIsNotPositive() {
assertThatThrownBy(() -> calculator.calculate(BigDecimal.ZERO, CustomerTier.GOLD))
.isInstanceOf(IllegalArgumentException.class)
.hasMessage("Order amount must be positive");
}
}
@ParameterizedTest+@CsvSourcekombiniert alle 3 Tier-Fälle in einen Test, reduziert doppelten Test-Code.- Die Zeile
assertThat(result).isEqualByComparingTo(...)vergleichtBigDecimalkorrekt (vermeidet den Fehler, dassequalsdie Skala beachtet). - Der andere Fall prüft die Exception mit ihrer Meldung.
AI arbeitet hier schnell, weil es alle Grenzfälle aufzählt (du würdest leicht den Fall orderAmount <= 0 vergessen), aber du musst die erwarteten Werte überprüfen – AI rechnet oft falsch.
5. AI zum Generieren von Javadoc und Zusammenfassen von Legacy-Code nutzen
Bei altem Code ohne Kommentare fasst AI schneller zusammen, als wenn du jede Zeile einzeln liest. Beispiel: Du hast ein komplexes Code-Fragment:
public List<Order> filterEligibleOrders(List<Order> orders) {
return orders.stream()
.filter(o -> o.getStatus() == OrderStatus.PAID)
.filter(o -> o.getCreatedAt().isAfter(LocalDate.now().minusDays(30)))
.filter(o -> o.getItems().stream().anyMatch(Item::isRefundable))
.toList();
}
Prompt: „Schreibe Javadoc für diese Methode, nenne explizit die 3 Filter-Bedingungen.”
AI gibt zurück:
/**
* Filtert die Liste der Bestellungen, die für Rückerstattungsverarbeitung
* berechtigt sind. Bedingungen: die Bestellung muss Status PAID haben,
* wurde in den letzten 30 Tagen erstellt, und hat mindestens ein Item,
* das Rückerstattung erlaubt.
*
* @param orders die Input-Bestellungsliste
* @return die Liste der Bestellungen, die alle drei Bedingungen erfüllen
*/
Das spart Zeit beim Onboarding neuer Entwickler für alte Codebases – du fügst eine Menge Methoden ein, AI gibt Javadoc-Entwürfe zurück, du korrigierst nur Fachbegriffe.
6. Automatisierte Code-Reviews mit AI in der CI
Du kannst einen Schritt hinzufügen, der AI-Code-Review des Diff in der Pipeline aufruft, um Fehler früh zu erkennen, bevor Menschen reviewen. Ein einfaches Beispiel in GitHub Actions mit einem API-Aufruf-Script:
name: ai-review
on: [pull_request]
jobs:
review:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Get diff
run: git diff origin/main...HEAD > diff.txt
- name: Call AI review
run: |
curl -s https://api.openai.com/v1/chat/completions \
-H "Authorization: Bearer ${{ secrets.OPENAI_API_KEY }}" \
-H "Content-Type: application/json" \
-d "$(jq -n --rawfile diff diff.txt \
'{model:"gpt-4o-mini", messages:[{role:"user", content: ("Review den folgenden Java-Diff, nenne nur kritische Probleme: " + $diff)}]}')" \
> review.json
git diff origin/main...HEAD > diff.txt– erfasst genau die geänderten Code-Teile im PR, vermeidet das Senden des ganzen Repos (kostet Tokens, ist langsam).jq -n --rawfileerzeugt sicheren JSON-Body, vermeidet Escape-Fehler bei Sonderzeichen im Code.- Das Ergebnis
review.jsonkannst du in einem weiteren Step als Kommentar auf dem PR posten.
Hinweis: AI-Review ersetzt keinen Senior-Review. Es erkennt nur offensichtliche Fehler (fehlende Null-Checks, leere catch-Blöcke, grundlegende SQL-Injection). Merge keinen PR nur weil AI „genehmigt” hat.
7. Häufige Fehler und wann AI nicht nutzen sollte
Ein paar praktische Fallstricke bei der Nutzung von LLM in Java-Projekten:
- Halluzinierte APIs, die nicht existieren: AI kann auffordern, Methoden wie
Order.markAsRefundable()aufzurufen, die die echte Klasse gar nicht hat. Kompiliere immer zuerst, bevor du vertraust. - Syntaktisch korrekter Code, aber falsche Version: AI mischt gerne Java-8-Stil (
new ArrayList<>()) mit Java-21-Syntax (List.of(...)) – du musst später nach Team-Convention normalisieren. - Sicherheitsleck: Kopiere keine Konfiguration mit Secrets, Connection Strings oder echten Kundendaten in Prompts an Drittanbieter-AI-Services.
- Vager Prompt → vager Output: „Schreib Tests für diese Klasse” gibt viel schwächere Ergebnisse als ein Prompt, der explizit die Grenzfälle nennt.
- Nicht verwenden für: Zinsberechnungen, Steuern oder compliance-relevanten Code, wo Fehler rechtliche Konsequenzen haben – AI sollte nur beim Schreiben des Gerüsts helfen, die Core-Logik muss ein Domänen-Experte gründlich mit echten Test-Fällen überprüfen, nicht nur AI-generierte Tests.
Eine kleine Checkliste, die du jedes Mal anwenden solltest, wenn AI Code generiert:
1. Kompiliert der Code?
2. Decken die AI-Tests echte Grenzfälle ab, oder nur „logisch klingende" Fälle?
3. Sind irgendwelche Geheimnisse in den Prompt gerutscht?
4. Passt der Code-Stil zu deiner Team-Convention?
8. Fazit
AI hilft dir am meisten bei wiederholten Aufgaben und schnellen Entwürfen: Test-Cases generieren, Stacktraces erklären, Javadoc schreiben, erste diff-Reviews. Spring AI macht LLM-Integration in Java-Apps dank weniger Konfigurationszeilen und ChatClient einfach.
Das Wichtigste: du musst alle Outputs sorgfältig überprüfen – AI spart Schreib-Zeit, nicht aber Zeit zum Verstehen und Validieren. Nutze es richtig und mit dem richtigen Vertrauenslevel, und du sparst viele wiederholte Stunden pro Woche, ohne Code-Qualität zu opfern.