Salta al contenuto principale

Classi di configurazione in Spring Boot: annotazione @Configuration

Profile picture for user luca77king

Quando si sviluppa un’applicazione con Spring Boot, uno dei concetti chiave è la configurazione del contesto dell’applicazione, ovvero l’insieme di oggetti (bean) che il framework gestisce automaticamente. Questa configurazione stabilisce come i componenti vengono creati, inizializzati e collegati tra loro. In un progetto moderno, Spring Boot automatizza gran parte di questo processo tramite auto-configuration, ma lascia al programmatore la possibilità di intervenire con classi di configurazione personalizzate.

Le classi di configurazione permettono di aggiungere, modificare o sostituire i comportamenti di default dell’applicazione, mantenendo il codice ordinato e facilmente gestibile. L’annotazione @Configuration è il punto d’ingresso di questo meccanismo: indica a Spring che la classe deve essere analizzata e che i metodi al suo interno possono definire dei bean.

Cos’è e come funziona una classe @Configuration

Una classe annotata con @Configuration è una classe Java normale che Spring analizza durante l’avvio per creare i bean che andranno a comporre il contesto dell’applicazione (ApplicationContext).
Quando Spring incontra un metodo annotato con @Bean, esegue quel metodo e registra il valore restituito come bean gestito. In questo modo non è necessario istanziare manualmente gli oggetti nel codice: basterà iniettarli dove servono tramite dependency injection.

Ecco un esempio semplice:

@Configuration
public class AppConfig {

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();
    }
}

In questo caso, Spring crea automaticamente un bean PasswordEncoder che può essere usato ovunque nel progetto semplicemente dichiarandolo come dipendenza:

@Service
public class UserService {

    private final PasswordEncoder encoder;

    public UserService(PasswordEncoder encoder) {
        this.encoder = encoder;
    }

    public void register(String password) {
        String encrypted = encoder.encode(password);
        // logica di salvataggio utente
    }
}

Non è necessario "usare" manualmente la classe AppConfig: è Spring Boot stesso, grazie alla scansione automatica dei componenti, a rilevarla e registrarla nel contesto.
Le classi di configurazione vengono scansionate se si trovano nel package principale o nei suoi sottopacchetti, cioè dove risiede la classe annotata con @SpringBootApplication.

Configurazioni modulari e @Import

In applicazioni di grandi dimensioni, è utile separare le configurazioni per modulo (ad esempio una per la sicurezza, una per il database, una per i servizi esterni).
Spring consente di unire più configurazioni in un’unica applicazione tramite l’annotazione @Import, che permette di importare altre classi di configurazione.

@Configuration
@Import({DatabaseConfig.class, SecurityConfig.class})
public class AppConfig {
}

In questo modo, Spring carica automaticamente anche le configurazioni dichiarate nelle altre classi importate, rendendo il progetto più modulare e scalabile.

Configurazioni per ambiente con @Profile

In molti contesti, è necessario definire configurazioni diverse a seconda dell’ambiente — sviluppo, test o produzione.
L’annotazione @Profile consente di associare una configurazione o un bean a un profilo specifico. Spring caricherà solo quelli relativi al profilo attivo, impostato ad esempio nel file application.yml o come variabile d’ambiente.

@Configuration
@Profile("dev")
public class DevDatabaseConfig {

    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:h2:mem:devdb");
        return ds;
    }
}
@Configuration
@Profile("prod")
public class ProdDatabaseConfig {

    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl("jdbc:mysql://prod-server:3306/appdb");
        ds.setUsername("appuser");
        ds.setPassword("secret");
        return ds;
    }
}

Nel file application.yml sarà sufficiente indicare quale profilo attivare:

spring:
  profiles:
    active: dev

Questo approccio consente di passare da un ambiente all’altro senza modificare il codice, mantenendo tutto centralizzato e pulito.

Configurazioni basate su proprietà con @ConfigurationProperties

Un ulteriore passo verso una configurazione ordinata è l’uso di @ConfigurationProperties, che permette di mappare parametri definiti nei file application.yml o application.properties in oggetti Java.

@Configuration
@ConfigurationProperties(prefix = "app.datasource")
public class DataSourceConfig {

    private String url;
    private String username;
    private String password;

    @Bean
    public DataSource dataSource() {
        HikariDataSource ds = new HikariDataSource();
        ds.setJdbcUrl(url);
        ds.setUsername(username);
        ds.setPassword(password);
        return ds;
    }

    // getter e setter
}

E la relativa configurazione:

app:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb
    username: myuser
    password: mypassword

Questo approccio è ideale per gestire parametri sensibili o variabili d’ambiente senza inserirli direttamente nel codice.

Quando usare @Configuration

Usare @Configuration è utile in tutti i casi in cui l’auto-configurazione di Spring Boot non è sufficiente o quando serve definire un comportamento specifico, come:

  • sostituire o personalizzare un bean di sistema (es. un ObjectMapper custom);

  • creare servizi comuni a più moduli;

  • configurare librerie esterne non gestite da Spring;

  • separare le configurazioni per ambiente o per ambito funzionale.

Nella maggior parte delle applicazioni, basta dichiarare le classi e lasciare che Spring le rilevi automaticamente: non serve istanziarle o richiamarle nel codice. L’unica accortezza è che si trovino in un package scansionato dal componente principale di Spring Boot.

Conclusione

L’annotazione @Configuration rappresenta la base della configurazione manuale in Spring Boot.
Permette di creare bean in modo controllato, definire logiche di inizializzazione, separare la configurazione dalla logica applicativa e adattare l’ambiente di esecuzione alle diverse esigenze.
Combinata con @Import, @Profile e @ConfigurationProperties, consente di costruire architetture modulari, flessibili e professionali, mantenendo al tempo stesso la semplicità e la potenza del modello Spring.