Exploration des diverses utilisations de l'annotation @Autowired en Spring

L'annotation @Autowired est l'un des piliers de l'injection de dépendances au sein de l'écosystème Spring. Bien que son usage sur les champs soit le plus courant, elle offre une flexibilité considérable lorsqu'elle est appliquée aux constructeurs, aux méthodes de configuration ou combinée avec d'autres annotations comme @Bean.

1. Injection par champ (Field Injection)

Il s'agit de la forme la plus simple, où l'annotation est placée directement sur une variable d'instance. Le conteneur IoC de Spring injecte la dépendance requise lors de l'instanciation du bean.

@Service
public class DocumentService {
    @Autowired
    private StorageProvider storageProvider;
}

2. Injection par constructeur

Spring favorise l'injection par constructeur pour garanitr l'immutabilité et s'assurer que les dépendances requises ne sont pas nulles.

Si une classe ne possède qu'un seul constructeur, l'annotation @Autowired est facultative depuis Spring 4.3.

@Component
public class OrderProcessor {
    private final PaymentGateway gateway;

    // L'annotation @Autowired est implicite ici
    public OrderProcessor(PaymentGateway gateway) {
        this.gateway = gateway;
    }
}

En présence de plusieurs constructeurs, l'annotation devient nécessaire pour indiquer à Spring lequel utiliser pour l'injection.

@Component
public class TaskRunner {
    private final Executor executor;

    public TaskRunner() {
        this.executor = Executors.newSingleThreadExecutor();
    }

    @Autowired
    public TaskRunner(Executor customExecutor) {
        this.executor = customExecutor;
    }
}

3. Injection via des méthodes (Setter et méthodes arbitraires)

L'annotation peut être appliquée sur des méthodes de type "setter" ou n'importe quelle méthode classique. Spring appellera cette méthode une fois le bean instancié, en injectant les arguments nécessaires.

@Component
public class CacheManager {
    private List<CacheStore> stores;

    @Autowired
    public void registerCacheStores(List<CacheStore> stores) {
        this.stores = stores;
    }
}

4. Utilisation au sein des classes de configuration avec @Bean

Dans une classe annotée @Configuration, @Autowired peut être utilisé pour injecter des dépendances dans les paramètres d'une méthode de fabrique. Cependant, pour les paramètres de méthodes @Bean, Spring effectue l'injection automatiquement même sans l'annotation.

@Configuration
public class NetworkConfig {

    @Bean
    public HttpClient customClient(SslContext sslContext) {
        return new HttpClient(sslContext);
    }

    @Bean
    public SslContext sslContext() {
        return new SslContext();
    }
}

5. Comportement du paramètre required

Le comporetment de @Autowired change selon que le paramètre required est défini sur true (par défaut) ou false, particulièrement lorsqu'il est appliqué sur une méthode.

  • @Autowired(required = true) : Si les arguments de la méthode ne peuvent pas être résolus dans le contexte applicatif, Spring lèvera une exception au démarrage.
  • @Autowired(required = false) :
    • Si la méthode ne possède pas de paramètres, elle est exécutée une fois après l'initialisation du bean.
    • Si la méthode possède des paramètres et que ceux-ci sont disponibels dans le conteneur, Spring injecte les dépendances et exécute la méthode.
    • Si l'un des paramètres est introuvable dans le conteneur, la méthode n'est tout simplement pas appelée.
@Component
public class OptionalModuleLoader {
    
    // Cette méthode ne sera exécutée que si un bean de type Plugin est présent
    @Autowired(required = false)
    public void configurePlugin(Plugin optionalPlugin) {
        System.out.println("Configuration du plugin : " + optionalPlugin.getName());
    }
}

6. Cas des méthodes sans paramètres

Il est possible d'annoter une méthode ne prenant aucun argument avec @Autowired. Dans ce cas, la méthode agit comme une méthode de post-initialisation (similaire à @PostConstruct), et sera déclenchée par le cycle de vie de Spring une fois les injections de champs terminées.

@Component
public class LifecycleWatcher {
    
    @Autowired
    public void onStartup() {
        // Logique exécutée au démarrage après injection des dépendances
    }
}

Étiquettes: Spring Framework Dependency Injection Java Core IoC Container Spring Boot

Publié le 27 juin à 03h30