我在Restlet Web服务器中使用Guice,并且有一种我无法弄清楚的模式:如何注入特定用户或特定请求的对象。
假设我们要求列出属于项目的所有小部件。查找Widgets的服务需要Project实例。系统中有许多项目。
我的代码目前看起来像这样:
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;
}
}
这很好用,但它很笨拙,我希望有更好的方法。直接注入正确的Project对象会很棒。有没有办法做到这一点?
到目前为止,我已经探索了AssistedInject,它提供了一个与我的Lookup非常相似的工厂对象。我接近使用自定义注释/注入的答案,但由于Restlet属性映射直到注入后才填充,因此无法完成。已阅读GitHub文档和用户指南。无法发现任何东西。
我想结束这样的事情:
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;
}
配置中的(当然)@Provides方法,该方法将查找路径变量并使用查找。但是,我无法想出一种方法将路径名称或Resource实例作为变量提供给提供者方法。这可能吗?任何帮助表示赞赏!
答案 0 :(得分:0)
您的愿景:您不能注入“getWidgets”...注入会在您创建widgetResource的那一刻发生,所以基本上一旦您的应用程序/服务器启动。
除此之外,它看起来非常好。您有一个REST资源,它接受一个项目参数并使用服务来查找小部件。
如果您事先了解所有可能的项目名称,则可以使用guice'mapBinder代替服务。
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(...);
}
}