Né des critiques à propos des problèmes liés aux fichiers de configuration XML définissant les contextes du conteneur, Spring Java Configuration ou JavaConfig était destiné à être une alternative qui permettrait de s’en affranchir en présentant  une solution basée sur les annotations dont le succès n’a cessé de percer depuis leur apparition dans la version 5 de Java.

Ainsi, avec JavaConfig les contextes Spring ne sont autres que des classes java (qui toutefois, ne sont pas de simples Pojos) ; ce qui devrait naturellement pallier à certaines contraintes classiquement associées à l’ancien modèle de configuration telles la verbosité, le typage faible ou le refactoring, et qui ont été, d’ailleurs, en grande partie résolus par Spring IDE ; mais surtout, à mon avis, de changer la manière avec laquelle on perçoit cette notion de configuration et sa gestion. C’est que l’intérêt du passage de XML à java est beaucoup plus important si on considère le passage au monde de l’orienté object, qui est de nos jours le paradigme le plus évolué et le plus mature.

En effet, cela permet de bénéficier de la puissance des concepts de l’orienté objet (abstraction, encapsulation, polymorphisme, découplage) et incitera à appliquer les principes de conception qui font leur succès tels que la SOC (separation of concerns), la hiérarchisation ou encore la « ré-utilisabilité », et qui, même s'ils étaient en partie d’actualité avec les fameux fichiers XML, n’étaient pas toujours évidents à mettre an place.

De ce fait, l’avènement de JavaConfig fera naître des patterns de configuration évolués, chose qui n’a pu être vraiment établi en quelques années de configuration XML. C’est que les possibilités offertes donnent beaucoup de flexibilité et de choix pour résoudre cette problématique de configuration.

Outre les possibilités offertes par la configuration XML et reprises par JavaConfig tel que l’aggrégation simple de contextes :

 

@Configuration

@Import({ContextA.class,ContextB.class})

public class AggregatedApplicationContexts {

 

    //...

}

 

 Qui peut même inclure des fichiers configurations xml :

 

@Configuration

@Import({ContextA.class,ContextB.class})

@ImportXml(locations="context.xml")

public class MixedApplicationContexts {

 

    //...

}

 

Et là, il faut noter que les configurations faites avec Javaconfig sont entièrement compatibles avec celles en XML et que l’association donc la ré-utilisabilité des anciens contextes est garantie; ce qui permet d’une part, l’intégration de JavaConfig dans des applications utilisant déjà la configuration XML ; et d’autre part, de fournir une solution de plus, qui coexiste avec les précédentes et donc de donner à l’utilisateur la liberté de choisir la possibilité la plus adéquate selon le besoin et les contraintes imposées par le contexte.

 

On pourrait aussi, faire hériter des contextes comme de simples classes.

 

@Configuration

public class ContextB extends ContextA{

 

    @Override

    protected @Bean Component bean() {

        //...

      bean = super.bean();

      bean.setXXX(XXX);

      //...    

    }

}

 

Et là, ce qui diffère par rapport à la configuration XML, c’est qu’on bénéficie de mécanismes de surcharge plus évolués que ceux proposés par cette dernière et qui permettent d’une part d’étendre cette action sur des beans invisibles depuis des contextes extérieurs (protected ou package) ; et d’autre part de réutiliser en partie la définition à surcharger. Ce qui amène aussi à noter un autre point fort de cette méthode de configuration : la définition dynamique des beans, un peu comme avec les langages de scripts dynamiques tel que Beanshell ou Groovy (<lang /> dans xml) mais sans être obligé d’ajouter de telles librairies.  

 

Une autre fonctionnalité, qui pourrait être très utile, est la capacité de gérer les contextes Spring comme étant eux-mêmes des beans ordinaires. Ainsi ils bénéficient de toutes les facilités du conteneur dont l’injection, soit pour recevoir des dépendances depuis d’autres contextes :

 

@Configuration

@AnnotationDrivenConfig

public class Context{

    @Autowired

    private ComponentA componentA;

    @Bean

    public ComponentB component(){

          ComponentB component = new ComponentB();

          component.setComponentA(componentA);

          return component;

    }

    public void setComponentA(ComponentA componentA) {

          this.componentA = componentA;

    }    

}

 

 

soit pour être eux-mêmes injectés comme tels.

 

@Configuration

@AnnotationDrivenConfig

public class Context{

    @Autowired

    private ComponentsContextA componentsContextA;

   

    @Bean

    public ComponentB component(){

          ComponentB component = new ComponentB();

          component.setComponentA(componentsContextA.componentA());

          return component;

    }

    public void setComponentsContextA(ComponentsContextA componentsContextA) {

          this.componentsContextA = componentsContextA;

    }    

}

 

Enfin, et pour s’en tenir qu’à cela, je dirais que même si cela a pris longtemps pour sortir de l’ombre et bénéficier d’un peu plus d’attention en étant intégré dans l’arborescence principale de la nouvelle release de Spring (la version 3), JavaConfig aura un impact réel et important dans l’univers de Spring et sûrement changera la manière d’utiliser ce framework.