【问题标题】:Can I do this with GUICE我可以用 GUICE 做到这一点吗
【发布时间】:2012-12-21 13:08:46
【问题描述】:

假设我定义了以下类:

public interface A {}

public class A1 implements A {}

public class A2 implements A {}

public class XServlet<T extends A> extends HttpServlet {
    public XServlet(T delegate){}
}

另外,在我的一个 Guice 模块中,我有愚蠢的绑定:

bind(A.class).annotatedWith(Names.named("a1")).to(A1.class);
bind(A.class).annotatedWith(Names.named("a2")).to(A2.class);

现在我需要创建一个 ServletModule,它定义了两个具有不同参数的“XServlet”实例。对于“/x”模式,我希望它使用绑定到 A.class 并用“a1”注释的任何内容,对于“/y”模式,我希望它使用任何绑定到 A.class 并用“a2”注释的内容。比如:

serve("/x").with(???);
serve("/y").with(???);

应该用什么代替'???'?有可能吗?

【问题讨论】:

    标签: guice guice-servlet


    【解决方案1】:

    这里有两个问题:一个是用serve方法改变XServlet的绑定注解,另一个是根据XServlet的注解改变A的绑定。

    serve 方法的一半很容易解决:手动创建一个Key。这会将“/x”绑定到@Named("a1") XServlet

    serve("/x").with(Key.get(XServlet.class, Names.named("a1")));
    

    后半部分被称为“机器人腿问题”,可以使用私有模块解决:

    install(new PrivateModule() {
      @Override void configure() {
        // These are only bound within this module, and are not visible outside.
        bind(A.class).to(A1.class);
        bind(XServlet.class).annotatedWith(Names.named("a1"));
        // But you can expose bindings as you'd like.
        expose(XServlet.class).annotatedWith(Names.named("a1"));
      }
    });
    

    更新:如果您之前提到的命名绑定无法移动到私有模块,您始终可以将私有模块中的非注解绑定绑定到另一个模块中的注解绑定。私有模块中的绑定应该是这样的:

    // Fulfill requests for an unannotated A by looking up @Named("a1") A,
    // though @Named("a1") A is bound elsewhere.
    bind(A.class).to(Key.get(A.class, Names.named("a1")));
    

    如果您尝试绑定其中的十几个,您可能会发现创建一个如下所示的私有静态函数会更容易:

    private static Module moduleForServlet(
        final Class<? extends A> aClass, final String namedAnnotationString) {
      return new PrivateModule() { /* see above */ };
    }
    

    文档:

    【讨论】:

    • 谢谢杰夫。但是您的解决方案并不能解决我的问题。它仍然需要我有“bind(A.class).to(A1.class);”在我的私人模块中 - 这正是我想要避免的。正如我所提到的,我已经在另一个模块中拥有该绑定,我无法移动到绑定 servlet 的模块。
    • @andrew.z 您可以使用与bind(A.class).to(Key.get(A.class, Names.named("a1"))) 相同的技术。我更新了我的答案以进行演示。我认为没有一个 Guice 功能会自动为所有注释 N 绑定 XServlet-with-N 以在单个语句中使用依赖项 YourDependency-with-N。
    猜你喜欢
    • 2015-04-11
    • 2011-01-30
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多