Spring Boot — Cheat Sheet

Tag: spring-boot, java, backend, microservices, rest-api, autoconfiguration

Livello: intermedio

TL;DR: Framework convention-over-configuration per creare applicazioni Spring stand-alone, production-ready, con server Tomcat integrato e gestione automatica delle dipendenze.

Concetti chiave

Auto-configuration configura automaticamente i bean rilevando le librerie presenti nel classpath.

Starter POMs aggregano dipendenze e versioni compatibili evitando conflitti transitivi Maven o Gradle.

Embed Tomcat o Netty integrato permette di produrre un singolo fat JAR eseguibile.

Spring Boot Actuator espone endpoint HTTP e JMX per metriche, healthcheck e tracing.

@SpringBootApplication aggrega @Configuration, @EnableAutoConfiguration e @ComponentScan.

Gestione dei profili tramite application-{profile}.properties o file YAML dedicati.

Inversion of Control e Dependency Injection delegano il ciclo di vita degli oggetti all'ApplicationContext.

Externalized Configuration permette di sovrascrivere valori da variabili d'ambiente, CLI o file esterni.

Domande tipiche e risposte pronte

Q: Qual e' la differenza principale tra Spring Framework e Spring Boot?R: Spring Framework fornisce il core per la Dependency Injection e richiede molta configurazione manuale XML o Java. Spring Boot aggiunge auto-configuration, starter POMs e server embedded per produrre app stand-alone con zero boilerplate.

Q: Come funziona @EnableAutoConfiguration a runtime?R: Scansiona il file META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports per caricare classi di configurazione condizionali con annotazioni @ConditionalOnClass o @ConditionalOnMissingBean.

Q: Perche' si preferisce la constructor injection rispetto alla field injection con @Autowired?R: La constructor injection garantisce l'immutabilita' con campi final, previene dipendenze parziali a runtime e rende i test unitari immediati senza dover istanziare il contesto Spring.

Q: Come gestisci transazioni complesse tra piu' layer applicativi?R: Uso @Transactional al livello Service gestendo propagation e rollback forzato su eccezioni non controllate o custom controllate via attributo rollbackFor.

Insidie e errori comuni

Component scan mancante perche' i package secondari non sono sottomessi al package della classe principale.

Cicli di dipendenze bloccanti a runtime se non risolti tramite refactoring o @Lazy.

Chiamata interna a metodi annotati @Transactional dallo stesso bean, che bypassa il proxy CGLIB rendendo la transazione inefficace.

Esposizione involontaria di endpoint sensibili di Actuator in ambiente di produzione.

Leak di memoria nei test d'integrazione causato da troppi contesti sporcati e ricaricati tramite @DirtiesContext.

Snippet e comandi

@RestController
@RequestMapping("/api/v1/orders")
public class OrderController {
    private final OrderService orderService;

    public OrderController(OrderService orderService) {
        this.orderService = orderService;
    }

    @PostMapping
    public ResponseEntity<OrderResponse> create(@Valid @RequestBody OrderRequest req) {
        OrderResponse created = orderService.createOrder(req);
        return ResponseEntity.status(HttpStatus.CREATED).body(created);
    }
}

Bash

# Avvio rapido con profilo di staging
./mvnw spring-boot:run -Dspring-boot.run.profiles=staging

# Build del fat JAR ed esecuzione
./mvnw clean package -DskipTests
java -jar target/app-0.0.1-SNAPSHOT.jar --server.port=8081

Da ripassare

[ ] Meccanismo interno dei proxy CGLIB e JDK Dynamic Proxy

[ ] Creazione di Custom Auto-configuration con starter proprietari

[ ] Differenze tra @MockBean e @SpyBean nei test con @WebMvcTest

[x] Ciclo di vita dei bean e hook @PostConstruct e @PreDestroy

[x] Configurazione datasource e connection pooling HikariCP

Jarvis Interviews
Jarvis