使用字段名作为键从属性文件中将值注入字段

时间:2013-07-18 09:50:25

标签: dependency-injection annotations guice

在guice中,您可以使用@Named注释将属性文件中的值注入类字段。

@Inject
@Named("nameLengthMin")
private int nameLengthMin;

我想构建一个不需要键参数的@Named注释版本,而是使用字段名作为键来搜索属性文件。

// takes field name as key
@Inject
@Named
private int nameLengthMin;

我正在试图弄清楚如何使用guice来实现这一目标,但我很擅长使用guice并编写自己的注释。

如何编写可以将带注释的字段作为参数的注释?

2 个答案:

答案 0 :(得分:1)

这可以通过使用自定义注入来实现,请参阅https://code.google.com/p/google-guice/wiki/CustomInjections

如果使用Inject和Named,则必须处理guice的内部实现,因此我建议创建一个自定义的“InjectProperty”绑定注释(如InjectLogger)。然后,您可以按照示例操作,“PropertyMembersInjector”可以读取属性并检查字段名称是否为有效键,然后转换/转换属性值并在字段上设置它。 这将是一些编码,但它可行。

答案 1 :(得分:0)

我知道我正在挖掘旧帖,但我想与其他人分享我的调查结果。

这个功能很久以前就已经requested了,但它还没有得到支持。执行此操作的最合适的注释是JSR 250' @Resource注释。 @ jan-galinski并不错,但有第三方解决方案已经为你完成了这项工作。

GuiceyFruit添加了此功能,但它似乎被放弃了(并非所有功能都适用于Guice 3)。尽管如此,这是一个如何做到的例子

@GrabResolver(name='GuiceyFruit', root='http://guiceyfruit.googlecode.com/svn/repo/releases')
@Grab(group='org.guiceyfruit', module='guiceyfruit-spring', version='2.0')
@Grab(group='com.google.inject', module='guice', version='3.0')
import javax.annotation.Resource;
import com.google.inject.name.Names;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import org.guiceyfruit.spring.SpringModule;

public class Main {
    public static void main(String[] args) {
        Box box = new Box();
        System.out.println("thingOne before injection='"+box.thingOne+"'");
        System.out.println("thingTwo before injection='"+box.thingTwo+"'");
        Guice.createInjector(new SpringModule(), new AbstractModule() {
            @Override
            protected void configure() {
                bind(String.class).annotatedWith(Names.named("thingOne")).toInstance("THING ONE");
                bind(String.class).annotatedWith(Names.named("thingTwo")).toInstance("THING TWO");
            }
        }).injectMembers(box);
        System.out.println("thingOne after injection='"+box.thingOne+"'");
        System.out.println("thingTwo after injection='"+box.thingTwo+"'");
    }

    public static class Box {
        @Resource public String thingOne;
        @Resource public String thingTwo;
    }
}

mycila Guice Extensions是另一种选择(我建议使用它,因为它仍然保持并提供更好的模块化)。我添加了此功能requested,因此很快就会推出。一旦它,这里是如何使用它:

@Grab(group='com.google.inject', module='guice', version='3.0')
@Grab(group='com.mycila.guice.extensions', module='mycila-guice-jsr250', version='3.6.ga')
import javax.annotation.Resource;
import com.google.inject.name.Names;
import com.google.inject.AbstractModule;
import com.google.inject.Guice;
import com.mycila.guice.ext.jsr250.Jsr250Module;
import com.mycila.guice.ext.closeable.CloseableModule;

public class Main {
    public static void main(String[] args) {
        Box box = new Box();
        System.out.println("thingOne before injection='"+box.thingOne+"'");
        System.out.println("thingTwo before injection='"+box.thingTwo+"'");
        Guice.createInjector(new Jsr250Module(), new CloseableModule(), new AbstractModule() {
            @Override
            protected void configure() {
                bind(String.class).annotatedWith(Names.named("thingOne")).toInstance("THING ONE");
                bind(String.class).annotatedWith(Names.named("thingTwo")).toInstance("THING TWO");
            }
        }).injectMembers(box);
        System.out.println("thingOne after injection='"+box.thingOne+"'");
        System.out.println("thingTwo after injection='"+box.thingTwo+"'");
    }

    public static class Box {
        @Resource public String thingOne;
        @Resource public String thingTwo;
    }
}

最后,Netflix的Governator也支持@Resource接线,但接线方式有点笨拙。这unit test看起来就像我能找到的最好的例子。