Как я могу настроить JSR-330 @Provider и @Inject @Named("foo") String ** программно ** в Spring?

Мы решили использовать 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 ответ

Решение

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

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

По поводу проблемы с Provider - Весна не поддерживает 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();
Другие вопросы по тегам