Как мне настроить JSR-330 @Provider и @Inject @Named ("foo") String ** программно ** в Spring? - PullRequest
10 голосов
/ 03 января 2011

Мы решили использовать Dependency Injection с аннотациями JSR-330 для наших будущих усилий по модульности и были очень довольны первым результатом, основанным на Guice 2. SVN.

Теперь нам нужно обеспечить и документировать черезмодульные тесты, которые нам нужны, также работают в Spring при программной настройке (нам нужна та же поддержка рефакторинга, что и в Guice, поэтому нет файлов XML).У меня проблемы с @Provider и @Inject @Named("foo") String, но я сделал простую @Inject работу с:

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

, где LIBL_Object - это базовый класс, который нужно вставить в , ноCORE_Provider не регистрируется, как я надеялся в Spring.

Реализация 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();
    }
}

, и я хочу, чтобы он был внедрен в

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

Также мы обнаружили, чтомы можем очень четко передать значения конфигурации, используя тег @Named.Этот код выглядит следующим образом:

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

, где мы можем зарегистрировать эту строку в Guice, используя

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

Итак, два вопроса:

  • Как сделатьЯ регистрирую класс @Provider в Spring 3 программно?
  • Как зарегистрировать строковую константу в Spring 3, чтобы @Named выбирал ее правильно?

1 Ответ

6 голосов
/ 03 января 2011

Короткий ответ: нет такой вещи, как программная конфигурация Spring.

Несмотря на то, что Spring и Guice поддерживают API-интерфейс JSR-330 и что Spring теперь можно конфигурировать без XML, их идеологиивсе еще очень разные.Spring опирается на статическую конфигурацию, либо в форме файлов XML, либо аннотированных классов Java.Поэтому простая попытка адаптации конфигурации в стиле Guice к Spring может вызвать трудности.

По поводу проблемы с Provider - Spring не поддерживает javax.inject.Provider так же, как привязка toProvider() в Guice (Кстати, это использование Provider не указано в документах JSR-330).Поэтому могут потребоваться некоторые специфичные для Spring аннотации, например,

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

Значение привязки, поступающее извне, может быть затруднено из-за статического характера конфигурации Spring.Например, в вашем случае это можно сделать так:

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();
...