Conversion du fichier XML spring en 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 spring, la classe @Configuration.

Supposons que j'ai un fichier XML spring qui ressemble à 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 à la place? Cela a-t-il un effet sur le code lui-même?

Author: Community, 2014-06-03

1 answers

(Avertissement - cette réponse est basée sur mon article de blog )

Migration de XML vers @Configuration

, Il est possible de migrer le fichier xml @Configuration, en quelques étapes:

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

    @Configuration
    public class MyApplicationContext {
    
    }
    
  2. Pour chaque <bean> balise de créer 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 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 XMLs ou @Configuration, nous pouvons utiliser les beans qu'ils déclarent dans notre contexte en déclarant un membre privé à la classe @Configuration comme suit:

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

    Ou l'utiliser directement comme paramètre dans la méthode qui définit le bean qui dépend de ce 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 des propriétés est très similaire à l'importation de 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;
    

    Cela peut également être utilisé avec les expressions SpEL.

  6. Afin de permettre à spring de traiter ces classes comme des conteneurs de beans, nous devons marquer cela dans notre xml principal en mettant cette balise dans le contexte:

    <context:annotation-config/>
    

    Vous pouvez maintenant importer des classes @Configuration exactement de la même manière que vous créeriez un simple haricot:

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

    Il existe des moyens d'éviter complètement spring XMLs mais ils ne sont pas dans la portée de cette réponse. Vous pouvez trouver l'une de ces options dans mon article de blog sur lequel je fonde ma réponse.


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 d'utiliser XMLs en raison de quelques avantages que je vois:

  1. Fautes de frappe - @Configuration les classes sont les compilations et les fautes de frappe ne permettent tout simplement pas les compilations
  2. Échouer rapidement (temps de compilation) - Si vous oubliez d'injecter un bean, vous échouerez au moment de la compilation et non à l'exécution comme avec XMLs
  3. Plus facile à naviguer dans ID - 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 tels que je les vois mais il y en a quelques-uns que je pourrais penser de:

  1. Abus - Le code est plus facile à abuser que XMLs
  2. Avec XMLs, vous pouvez définir des dépendances basées sur des classes qui ne sont pas disponibles pendant la compilation mais qui sont fournies pendant 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 y a des cas, il peut être.

Bottom line: Il est parfaitement correct de combiner les annotations XMLs, @Configuration et dans votre contexte d'application. Printemps ne se soucie pas de la méthode avec laquelle un bean a été déclaré.

 133
Author: Avi, 2017-05-23 12:18:19