Java Guice可以注入需要查找函数的东西吗?

Java Guice可以注入需要查找函数的东西吗?,java,dependency-injection,guice,Java,Dependency Injection,Guice,我在restletweb服务器中使用Guice,有一种模式我想不出来:如何注入特定于某个用户或某个请求的对象 假设我们请求列出属于一个项目的所有小部件。查找小部件的服务需要一个项目实例。系统中有许多项目 我的代码当前看起来像这样: public class WidgetResource extends ServerResource { //path: project/{project}/widgets private final WidgetService service;

我在restletweb服务器中使用Guice,有一种模式我想不出来:如何注入特定于某个用户或某个请求的对象

假设我们请求列出属于一个项目的所有小部件。查找小部件的服务需要一个项目实例。系统中有许多项目

我的代码当前看起来像这样:

public class WidgetResource extends ServerResource {

    //path: project/{project}/widgets

    private final WidgetService service;
    private final ProjectLookup projectLookup;

    @Inject
    public WidgetResource(WidgetService service, ProjectLookup projectLookup) {
        this.service = service;
        this.projectLookup = projectLookup;
    }

    @Get
    public WidgetCollection getWidgets() {
        String projectName = getAttribute("project"); //restlet lookup of path var
        Project project = projectLookup.get(projectName);
        WidgetCollection widgets = service.getWidgetsFor(project);
        return widgets;
    }

}
public class WidgetResource extends ServerResource {

    private final WidgetService service;

    @Inject
    public WidgetResource(WidgetService service) {
        this.service = service;
    }

    @Inject
    @Get
    public WidgetCollection getWidgets(@PathName("project") Project project) {
        WidgetCollection widgets = service.getWidgetsFor(project);
        return widgets;
    }
这很好,但很笨拙,我希望有更好的方法。直接注入正确的项目对象将非常好。有办法做到这一点吗

到目前为止,我已经研究了AssistedInject,它提供了一个与我的查找非常相似的工厂对象。我使用自定义注释/注入接近于答案,但由于Restlet属性映射直到注入之后才填充,所以没有结果。已阅读GitHub文档和用户指南。什么都看不见

我想以这样的方式结束:

public class WidgetResource extends ServerResource {

    //path: project/{project}/widgets

    private final WidgetService service;
    private final ProjectLookup projectLookup;

    @Inject
    public WidgetResource(WidgetService service, ProjectLookup projectLookup) {
        this.service = service;
        this.projectLookup = projectLookup;
    }

    @Get
    public WidgetCollection getWidgets() {
        String projectName = getAttribute("project"); //restlet lookup of path var
        Project project = projectLookup.get(projectName);
        WidgetCollection widgets = service.getWidgetsFor(project);
        return widgets;
    }

}
public class WidgetResource extends ServerResource {

    private final WidgetService service;

    @Inject
    public WidgetResource(WidgetService service) {
        this.service = service;
    }

    @Inject
    @Get
    public WidgetCollection getWidgets(@PathName("project") Project project) {
        WidgetCollection widgets = service.getWidgetsFor(project);
        return widgets;
    }

当然,@在配置中提供了查找路径变量并使用查找的方法。但是,我无法找到一种方法将路径名或资源实例作为变量传递给提供者方法。这可能吗?感谢您的帮助

对您的愿景:您不能注入getWidgets。。。注入发生在创建widgetResource的那一刻,因此基本上是在应用程序/服务器启动之后

除此之外,它看起来非常好。您有一个REST资源,它接受一个项目参数并使用一个服务来查找小部件

如果您事先知道所有可能的项目名称,那么可以使用guice而不是服务

public class WidgetsModule extends AbstractModule {
  protected void configure() {
    MapBinder<String, WidgetCollection> mapbinder
        = MapBinder.newMapBinder(binder(), String.class, WidgetCollection.class);
     mapbinder.addBinding("project1").toInstance(...);
     mapbinder.addBinding("project2").toProvider(...);
     mapbinder.addBinding("project3").to(...);
  }
}

实际上我更喜欢第一个版本的可读性!我并不反对你的观点——第一个代码示例非常简单。问题是,我们有一个复杂的查找系统和对象树,它们随项目或用户等不同而变化。由于列表是动态的,设计项目会被添加、删除、更改,因此我无法找到将其创建委托给Guice的方法,而且我们必须注入许多笨拙的查找对象。由于这是代码中重复且麻烦的模式,我希望有办法解决它。