Question Comment configurer JSR-330 @Provider et @Inject @Named (“foo”) String ** par programmation ** au printemps?


Nous avons décidé d'utiliser l'injection de dépendance avec les annotations JSR-330 pour nos futurs efforts de modularisation, et nous avons été très satisfaits du premier livrable basé sur SVN Guice 2.

Maintenant, nous devons nous assurer et documenter à travers les tests unitaires que les constructions dont nous avons besoin fonctionnent également au printemps quand elles sont configurées par programmation (nous voulons le même support de refactoring qu'avec Guice donc pas de fichiers XML). J'ai des problèmes avec @Provider et @Inject @Named("foo") String mais j'ai bien compris @Inject travailler avec:

ApplicationContext ctx = new AnnotationConfigApplicationContext(LIBL_Object.class, 
                                                                CORE_Provider.class);
this.object = ctx.getBean(LIBL_Object.class);

où LIBL_Object est la classe de base à injecter dans, mais le CORE_Provider ne s’enregistre pas comme je l’espérais au printemps.

L'implémentation de CORE_Provider est

package qa.jsr330.core;

import javax.inject.Provider;

public class CORE_Provider implements Provider<ProvidedInterface> {
    @Override
    public ProvidedInterface get() {
        return new CORE_Provided();
    }
}

et je veux qu'il soit injecté dans

package qa.jsr330.core;

import javax.inject.Inject;

public class LIBL_Object {

    private ProvidedInterface provided;

    public ProvidedInterface getProvided() {
        return provided;
    }

    @Inject
    public void setProvided(ProvidedInterface provided) {
        this.provided = provided;
    }
// Other stuff omitted.
}

Nous avons également constaté que nous pouvons transmettre des valeurs de configuration très clairement en utilisant le tag @Named. Ce code ressemble à:

String hostname;
@Inject
public void setHostname(@Named("as400.hostname") String hostname) {
    this.hostname = hostname;
}

où nous pouvons alors enregistrer cette chaîne avec Guice en utilisant

bindConstant().annotatedWith(Names.named("as400.hostname")).to(value);

Les deux questions sont donc:

  • Comment enregistrer le @Provider classe avec Spring 3 par programmation?
  • Comment enregistrer une chaîne constante avec Spring 3 afin que @Named le sélectionne correctement?

10
2018-01-03 10:43


origine


Réponses:


La réponse courte est la suivante: il n'y a pas de configuration programmatique du printemps.

Malgré le fait que Spring et Guice prennent en charge l'API JSR-330 et que Spring puisse être configuré sans XML maintenant, leurs idéologies sont encore très différentes. Spring s'appuie sur une configuration statique, sous la forme de fichiers XML ou de classes Java annotées. Par conséquent, une simple tentative d’adaptation de la configuration de style Guice au printemps peut entraîner des difficultés.

En ce qui concerne le problème avec Provider - Le printemps ne supporte pas javax.inject.Provider de la même façon que toProvider() contraignant dans Guice (au fait, cette utilisation de Provider n'est pas spécifié dans les documents JSR-330). Par conséquent, certaines annotations spécifiques à Spring peuvent être nécessaires, par exemple

@Configuration
public class CORE_Provider implements Provider<ProvidedInterface> {
      @Override @Bean
      public ProvidedInterface get() {
          return new CORE_Provided();
      }
} 

La valeur de liaison provenant de l'extérieur peut être difficile en raison de la nature statique de la configuration Spring. Par exemple, dans votre cas, cela peut se faire comme ceci:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(IBL_Object.class);
ctx.register(CORE_Provider.class);
ctx.registerBeanDefinition("as400.hostname",
    BeanDefinitionBuilder.rootBeanDefinition(String.class)
        .addConstructorArgValue(value).getBeanDefinition());
ctx.refresh();

6
2018-01-03 14:32