Como configuro JSR-330 @Provider e @Inject @Named (“foo”) String ** programaticamente ** no Spring?

10

Decidimos usar a Injeção de Dependência com anotações JSR-330 para nossos futuros esforços de modularização e ficamos muito satisfeitos com a primeira entrega baseada no SVN Guice 2.

Agora precisamos garantir e documentar, por meio de testes de unidade, que as construções de que precisamos também funcionam no Spring quando configuradas programaticamente (queremos o mesmo suporte de refatoração que o Guice para que não haja arquivos XML). Eu tenho problemas com @Provider e @Inject @Named("foo") String , mas deixei claro que @Inject funciona com:

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

onde LIBL_Object é a classe base a ser injetada em , mas o CORE_Provider não registra como eu esperava no Spring.

A implementação do CORE_Provider é

package qa.jsr330.core;

import javax.inject.Provider;

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

e eu quero que seja injetado em

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.
}

Também descobrimos que podemos passar valores de configuração muito claramente usando a tag @Named. Este código se parece com:

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

onde podemos registrar essa string com o Guice usando

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

Então as duas perguntas são:

  • Como faço para registrar a classe @Provider com o Spring 3 programaticamente?
  • Como faço para registrar uma constante de string com o Spring 3 para que @Named a selecione corretamente?
por Thorbjørn Ravn Andersen 03.01.2011 в 11:43
fonte

1 resposta

6

A resposta curta é: não existe configuração programática do Spring.

Apesar do fato de que Spring e Guice suportam a API JSR-330 e que Spring pode ser configurado sem XML agora, suas ideologias ainda são muito diferentes. O Spring depende da configuração estática, seja na forma de arquivos XML ou de classes Java anotadas. Portanto, a tentativa direta de adaptar a configuração no estilo Guice ao Spring pode gerar dificuldades.

Em relação ao problema com Provider - Spring não suporta javax.inject.Provider da mesma forma que toProvider() binding em Guice (a propósito, esse uso de Provider não está especificado em docs JSR-330) . Portanto, algumas anotações específicas do Spring podem ser necessárias, por exemplo

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

O valor de ligação vindo do exterior pode ser difícil devido à natureza estática da configuração da mola. Por exemplo, no seu caso, isso pode ser feito assim:

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();
    
por axtavt 03.01.2011 / 15:32
fonte