Как я могу настроить 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();