如何在Spring中以编程方式**配置JSR-330 @Provider和@Inject @Named(“foo”)String **?

时间:2011-01-03 10:43:05

标签: java spring jsr330

我们决定将依赖注入和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);

所以这两个问题是:

  • 如何以编程方式在Spring 3中注册@Provider类?
  • 如何在Spring 3中注册字符串常量,以便@Named正确选择它?

1 个答案:

答案 0 :(得分:6)

简短的回答是:没有Spring的程序化配置。

尽管Spring和Guice都支持JSR-330 API,并且现在可以在没有XML的情况下配置Spring,但它们的意识形态仍然非常不同。 Spring依赖于静态配置,可以是XML文件的形式,也可以是带注释的Java类。因此,直接尝试将Guice风格的配置适应Spring可能会产生困难。

关于Provider的问题 - Spring不支持javax.inject.Provider的方式与Guice中toProvider()绑定的方式相同(顺便说一下,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();