Spring — Cheat Sheet

Tag: spring, java, spring boot, dependency injection, ioc, aop, rest

Livello: intermedio

TL;DR: Panoramica dell'ecosistema Spring: IoC Container, Dependency Injection, bean lifecycle, Spring Boot e gestione REST.

Concetti chiave

Inversion of Control (IoC): delega la gestione del ciclo di vita degli oggetti al container.

Dependency Injection (DI): pattern per iniettare dipendenze tramite costruttore, setter o campo.

Spring Bean: oggetto istanziato, assemblato e gestito interamente dallo Spring IoC Container.

Scopi dei Bean (Scopes): singleton (default), prototype, request, session, application, websocket.

Iniezione via costruttore: approccio raccomandato per garantire immutabilita e facilitare i test unitari.

ApplicationContext: interfaccia avanzata del container che estende BeanFactory con eventi e messaggistica.

Spring Boot: semplifica la configurazione tramite auto-configuration, starter dipendenze e server embedded.

Aspect-Oriented Programming (AOP): separa cross-cutting concerns (logging, sicurezza, transazioni) dalla logica core.

Annotazioni core: @Component, @Service, @Repository, @Controller definiscono i diversi ruoli architetturali.

Transazionalita dichiarativa: gestione automatica del rollback e del commit tramite annotazione @Transactional.

Domande tipiche e risposte pronte

Q: Qual e la differenza tra BeanFactory e ApplicationContext?R: BeanFactory fornisce le funzionalita base di IoC e lazy loading. Io preferisco ApplicationContext perche aggiunge auto-wiring avanzato, supporto a eventi e internazionalizzazione.

Q: Perche e preferibile l'iniezione tramite costruttore rispetto a @Autowired su campo?R: L'iniezione via costruttore previene i NullPointerException, garantisce che i bean siano immutabili e permette di istanziare la classe nei test senza riflessione.

Q: Come funziona @Transactional in Spring?R: Spring crea un proxy AOP attorno al bean che apre una transazione, intercetta eventuali eccezioni runtime per il rollback ed esegue il commit al termine del metodo.

Insidie e errori comuni

Invocazione interna di metodi annotati con @Transactional: bypassa il proxy AOP e impedisce l'avvio della transazione.

Dipendenze circolari tra componenti: causano fallimenti all'avvio a meno di refactoring o uso temporaneo di @Lazy.

Dipendenza mutabile iniettata in un bean singleton: rischio concreto di race condition e concorrenza non thread-safe.

Ignorare la distinzione tra eccezioni unchecked (rollback di default) e checked (rollback non eseguito senza clausola rollbackFor).

Snippet e comandi

@Service
public class UserService {

    private final UserRepository userRepository;

    public UserService(UserRepository userRepository) {
        this.userRepository = userRepository;
    }

    @Transactional(readOnly = true)
    public User findById(Long id) {
        return userRepository.findById(id)
            .orElseThrow(() -> new EntityNotFoundException("User not found"));
    }
}

Java

@RestController
@RequestMapping("/api/v1/users")
public class UserController {

    private final UserService userService;

    public UserController(UserService userService) {
        this.userService = userService;
    }

    @GetMapping("/{id}")
    public ResponseEntity<User> getUser(@PathVariable Long id) {
        return ResponseEntity.ok(userService.findById(id));
    }
}

Da ripassare

[ ] Configurazione di @Transactional(rollbackFor = Exception.class)

[ ] Meccanismo di registrazione dei BeanDefinition nel container

[ ] Differenze tra @ControllerAdvice e @ExceptionHandler

[ ] Funzionamento interno dell'auto-configuration di Spring Boot

Jarvis Interviews
Jarvis