基于自定义注解的绑定

发布于 2024-11-24 17:35:50 字数 1139 浏览 0 评论 0原文

我对 stackoverflow 和 guice 都很陌生。我不确定我想做的事情是否可以通过技巧实现,但我确实希望如此。

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

public interface DocumentReader {
    MetaData readDocument() throws Exception
}

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

public enum FileType {
    doc,
    png,
    txt,
}

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

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

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

至此,我已经成功编写&测试了一个使用 MapBinder 的模块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 文档,但我只是没有找到实现此目标的方法(如果可能的话!)。任何帮助将不胜感激。

谢谢!

I'm new to both stackoverflow and guice. I'm not sure what I'm trying to do is possible with guice, but I sure hope it is.

My problem domain is that I'm trying to write a document reading system. I have defined an interface for a DocumentReader.

public interface DocumentReader {
    MetaData readDocument() throws Exception
}

I have also defined a enumeration defining supported file types (i.e. extensions).

public enum FileType {
    doc,
    png,
    txt,
}

I have an implementation for each FileType, providing details of how to parse that file type.

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

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

At this point, I have successfully written & tested a module that uses MapBinder & FactoryModuleProvider to inject each of these objects. Each DocumentReader implementation that exists is individually added to the MapBinder. What I'm hoping is that as additional implementations of DocumentReader are written, I could simply annotate them with which FileType(s) they support, and GUICE would be able to read the annotation and add them to the MapBinder appropriately (without me having to update the module per addition). What I've envisioned is something like this:

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

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

I've read through the GUICE documentation several times, but I'm just not seeing a way to accomplish this (if it is even possible!). Any help would be appreciated.

Thanks!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

季末如歌 2024-12-01 17:35:51

您可以让模块使用反射扫描类将进入的包,查找实现 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
  }
}

You could have your module scan the package(s) the classes will go in using reflection, looking for classes that implement DocumentReader and are annotated with @SupportedFileTypes. When it finds one, add it to the MapBinder for each file type.

If you don't want to scan the classpath, you could still simplify this for yourself by writing a method like this:

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
  }
}
姜生凉生 2024-12-01 17:35:51

了解其工作原理的最简单方法是查看 命名名称 类,以及它的使用方式

首先创建一个RequiredFileType注释,

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

然后注释依赖于文档阅读器的类,

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

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

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);

The easiest way to see how this works is to look at the source for the Named and Names class, and how it is used.

First create a RequiredFileType annotation,

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

Then annotate the class which depends on Document reader like,

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

Then create a RequiredFileTypes utility which is equivalent to Names (code ommitted), and in your module write code like,

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);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文