...如果需要手动构建实例,也许是由第 3 方工厂类?以前,(Jersey 1.x),你会做这样的事情:
public class MyInjectableProvider extends PerRequestTypeInjectableProvider<Context, MyInjectable> {
public MyInjectableProvider() {
super(MyInjectable.class);
}
@Override
public Injectable<MyInjectable> getInjectable(ComponentContext ic, Context context) {
MyInjectable myInjectableInstance = //...
return new Injectable<MyInjectable>() {
@Override
public MyInjectable getValue() {
return myInjectableInstance;
}
};
}
}
匿名本地类能够访问实例以在某个范围内返回。当您不使用具有默认构造函数的类时,这很有用,但需要根据每个请求构造它们。
Jersey 2.0 切换到 HK2 作为依赖注入框架,但遗憾的是,迁移页面 ( https://jersey.java.net/documentation/latest/migration.html ) 没有提供这种绑定的示例,并且HK2 文档没有提供使用 AbstractBinder 的示例。
为了详细说明,我正在尝试为我的资源提供资源本地、容器无关的 JPA EntityManager 实例。这些必须从单例工厂类中获取,并且应该只保留一个“工作单元”,这在我的情况下是一个请求。我知道有一些解决方法(只需注入工厂,或绑定到线程本地),但我发现以前的解决方案很优雅,如果可能的话想重新创建它。
编辑:
通过 HK2 javadocs 挖掘了一下,我发现类似的东西可以实现如下:
public class MyInjectableProvider extends AbstractBinder
implements Factory<MyInjectable> {
@Override
protected void configure() {
bindFactory(this).to(MyInjectable.class);
}
@Override
public MyInjectable provide() {
return getMyInjectable();
}
@Override
public void dispose(MyInjectable instance) {}
}
并注册它...
public class MyResourceConfig extends ResourceConfig {
public MyResourceConfig() {
register(new MyInjectableProvider());
}
}
这“似乎有效”,但似乎也有点不清楚。例如,从不调用 dispose()。此外,此绑定似乎隐含地表现为 RequestScoped。将配置修改为bindFactory(this).to(MyInjectable.class).in(RequestScoped.class);
似乎并没有真正改变行为。我错过了什么,还是这是预期的解决方案?