web-dev-qa-db-fra.com

Comprendre la classe Spring @Configuration

Suite à la question Comprendre l'utilisation de Spring @Autowired Je voulais créer une base de connaissances complète pour l'autre option de câblage à ressort, le @Configuration classe.

Supposons que j'ai un fichier XML printanier ressemblant à ceci:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
  xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

  <import resource="another-application-context.xml"/>

  <bean id="someBean" class="stack.overflow.spring.configuration.SomeClassImpl">
    <constructor-arg value="${some.interesting.property}" />
  </bean>

  <bean id="anotherBean" class="stack.overflow.spring.configuration.AnotherClassImpl">
    <constructor-arg ref="someBean"/>
    <constructor-arg ref="beanFromSomewhereElse"/>
  </bean>
</beans>

Comment puis-je utiliser @Configuration au lieu? Cela at-il une incidence sur le code lui-même?

103
Avi

Migration de XML vers @Configuration

Il est possible de migrer le xml vers un @Configuration En quelques étapes:

  1. Créez une classe annotée @Configuration:

    @Configuration
    public class MyApplicationContext {
    
    }
    
  2. Pour chaque balise <bean>, Créez une méthode annotée avec @Bean:

    @Configuration
    public class MyApplicationContext {
    
      @Bean(name = "someBean")
      public SomeClass getSomeClass() {
        return new SomeClassImpl(someInterestingProperty); // We still need to inject someInterestingProperty
      }
    
      @Bean(name = "anotherBean")
      public AnotherClass getAnotherClass() {
        return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse); // We still need to inject beanFromSomewhereElse
      }
    }
    
  3. Pour importer beanFromSomewhereElse, nous devons importer sa définition. Il peut être défini dans un fichier XML et nous allons utiliser @ImportResource:

    @ImportResource("another-application-context.xml")
    @Configuration
    public class MyApplicationContext {
      ...  
    }
    

    Si le bean est défini dans une autre classe @Configuration, Nous pouvons utiliser l'annotation @Import:

    @Import(OtherConfiguration.class)
    @Configuration
    public class MyApplicationContext {
      ...
    }
    
  4. Après avoir importé d'autres classes XML ou @Configuration, Nous pouvons utiliser les beans déclarés dans notre contexte en déclarant un membre privé à la classe @Configuration Comme suit:

    @Autowired
    @Qualifier(value = "beanFromSomewhereElse")
    private final StrangeBean beanFromSomewhereElse;
    

    Ou utilisez-le directement en tant que paramètre dans la méthode qui définit le bean qui dépend de cette beanFromSomewhereElse en utilisant @Qualifier Comme suit:

    @Bean(name = "anotherBean")
    public AnotherClass getAnotherClass(@Qualifier (value = "beanFromSomewhereElse") final StrangeBean beanFromSomewhereElse) {
      return new AnotherClassImpl(getSomeClass(), beanFromSomewhereElse);
    }
    
  5. L'importation de propriétés est très similaire à l'importation d'un bean à partir d'une autre classe xml ou @Configuration. Au lieu d'utiliser @Qualifier, Nous utiliserons @Value Avec les propriétés suivantes:

    @Autowired
    @Value("${some.interesting.property}")
    private final String someInterestingProperty;
    

    Ceci peut également être utilisé avec des expressions SpEL .

  6. Afin de permettre au printemps de traiter de telles classes comme des conteneurs de haricots, nous devons le marquer dans notre code XML principal en plaçant cette balise dans le contexte:

    <context:annotation-config/>
    

    Vous pouvez maintenant importer les classes @Configuration Exactement comme si vous créiez un bean simple:

    <bean class="some.package.MyApplicationContext"/>
    

    Il existe des moyens d'éviter complètement les XML de printemps, mais ils ne font pas partie de cette réponse. Vous pouvez trouver une de ces options dans mon article de blog sur lequel je me base.


Les avantages et les inconvénients de l'utilisation de cette méthode

Fondamentalement, je trouve cette méthode de déclaration des beans beaucoup plus confortable que l’utilisation de XML en raison de quelques avantages:

  1. Typos - Les classes @Configuration Sont compilées et les typos ne permettent tout simplement pas les compilations
  2. Échec rapide (temps de compilation) - Si vous oubliez d'injecter un bean, vous échouerez au moment de la compilation et non au moment de l'exécution, contrairement aux XML.
  3. Plus facile à naviguer dans l'IDE - entre les constructeurs de beans pour comprendre l'arbre de dépendance.
  4. Possibilité de déboguer facilement le démarrage de la configuration

Les inconvénients ne sont pas nombreux, mais il y en a quelques-uns auxquels je pourrais penser:

  1. Abus - Le code est plus facile à abuser que les XML
  2. Avec les XML, vous pouvez définir des dépendances basées sur des classes qui ne sont pas disponibles au moment de la compilation, mais sont fournies au moment de l'exécution. Avec les classes @Configuration, Vous devez avoir les classes disponibles au moment de la compilation. Habituellement, ce n'est pas un problème, mais il peut arriver que ce soit le cas.

En bout de ligne: Il est tout à fait judicieux de combiner XML, @Configuration Et annotations dans le contexte de votre application. Le printemps se moque de la méthode avec laquelle un haricot a été déclaré.

143
Avi