基于自定义注释的绑定

时间:2011-07-16 03:58:43

标签: java dependency-injection guice

我是stackoverflow和guice的新手。我不确定我想做什么是可能的guice,但我当然希望它是。

我的问题域是我正在尝试编写文档阅读系统。我已经为DocumentReader定义了一个接口。

public interface DocumentReader {
    MetaData readDocument() throws Exception
}

我还定义了一个定义支持的文件类型(即扩展名)的枚举。

public enum FileType {
    doc,
    png,
    txt,
}

我有每个FileType的实现,提供了如何解析该文件类型的详细信息。

public class MSWordReaderImpl implements DocumentReader {
    // ....
}

public class PlainTextReaderImpl implements DocumentReader {
    // ....
}

此时,我已经成功写了&测试了一个使用MapBinder& amp;的模块。 FactoryModuleProvider用于注入每个对象。存在的每个DocumentReader实现都单独添加到MapBinder。我希望的是,随着DocumentReader的其他实现的编写,我可以简单地使用它们支持的FileType来注释它们,并且GUICE将能够读取注释并将它们适当地添加到MapBinder(无需我每次添加更新模块)。我设想的是这样的:

@SupportedFileTypes( filetypes={ doc, docx } )
public class MSWordReaderImpl implements DocumentReader {
    // ....
}

@SupportedFileTypes( filetypes={txt} )
public class PlainTextReaderImpl implements DocumentReader {
    // ....
}

我已经多次阅读了GUICE文档,但我只是没有找到实现这一目标的方法(如果它甚至可能!)。任何帮助将不胜感激。

谢谢!

2 个答案:

答案 0 :(得分:1)

了解其工作原理的最简单方法是查看NamedNames类的来源,以及它是used的来源。

首先创建一个RequiredFileType注释,

@Retention(RUNTIME)
@Target({ ElementType.FIELD, ElementType.PARAMETER, ElementType.METHOD })
@BindingAnnotation
public @interface RequiredFileType {
  FileType value();
}

然后注释依赖于Document reader的类,

@Inject
ServiceRequiringWordReader(@RequiredFileType(doc) DocumentReader reader)

然后创建一个RequiredFileTypes实用程序,它等同于Names(代码省略),并在您的模块中编写代码,如

bind(DocumentReader.class)
    .annotatedWith(RequiredFileTypes.for(doc))
    .to(MSWordReaderImpl.class);
bind(DocumentReader.class)
    .annotatedWith(RequiredFileTypes.for(docx))
    .to(MSWordReaderImpl.class);
bind(DocumentReader.class)
    .annotatedWith(RequiredFileTypes.for(txt))
    .to(PlainTextReaderImpl.class);

答案 1 :(得分:1)

您可以让模块使用反射扫描类将进入的包,查找实现DocumentReader并使用@SupportedFileTypes注释的类。当找到一个时,将其添加到每个文件类型的MapBinder

如果您不想扫描类路径,您仍然可以通过编写如下方法来自行简化:

private void bindDocumentReaders(Class<? extends DocumentReader>... types) {
  for (Class<? extends DocumentReader> type : types) {
    FileType[] supportedFileTypes = type.getAnnotation(SupportedFileTypes.class)
        .filetypes();
    // add to MapBinder for each file type
  }
}