我正在尝试在Application构造函数(继承自ResourceConfig的东西)中初始化Jersey应用程序中的一些组件。看起来像这样
public Application(@Context ServletContext context,
@Context ServiceLocator locator)...
当我尝试在任何时候使用定位器时,我仍然无法使用locator.create(MyThing.class)方法创建我在AbstractBinder中注册的事物的实例。
我确定它们被正确绑定,因为它们通过@inject字段注释正确地注入到我的资源类中。
不同之处在于Jersey / HK2框架正在实例化我的资源类(正如预期的那样,因为它们位于我的包扫描路径中),但我似乎无法通过代码利用ServiceLocator。
我的最终目标是在拥有@Inject属性时注入其他非球衣类,例如。我有一个需要注入配置的数据库访问层的worker类。我想说
locator.Create(AWorker.class)
然后注射。
如何获得真实的ServiceLocator,它将注入我已经注册/绑定到Binder的所有内容? (或者我应该使用ServiceLocator以外的其他东西吗?)
答案 0 :(得分:2)
你是如何启动你的容器的?如果您使用的是ApplicationHandler,则只需拨打:handler.getServiceLocator()
即可。事实上,ServiceLocator是您希望用来访问依赖项的。
如果您正在启动servlet,我发现访问服务定位器的最佳方法是在我的启动类中设置Jersey功能:
private static final class LocatorSetFeature implements Feature {
private final ServiceLocator scopedLocator;
@Inject
private LocatorSetFeature(ServiceLocator scopedLocator) {
this.scopedLocator = scopedLocator;
}
@Override
public boolean configure(FeatureContext context) {
locator = scopedLocator; //this would set our member locator variable
return true;
}
}
该功能只需使用config.register(new LocatorSetFeature())在资源配置中注册。
根据容器的生命周期绑定其他组件的启动是很重要的,所以这仍然感觉有点hacky。您可以考虑将这些类添加为HK2容器中的第一类依赖项,并简单地将适当的依赖项注入到第三方类中(例如,使用Binder)。
答案 1 :(得分:1)
我将假设您正在启动servlet并具有扩展org.glassfish.jersey.server.ResourceConfig
的类,并且您的绑定已正确注册(例如,使用Binder和registerInstances)。然后,如果您想访问ServiceLocator以便执行其他初始化,则有两种选择:
一种方法是注册一个ContainerLifecycleListener(如此处in this post所示):
// In Application extends ResourceConfig constructor
register(new ContainerLifecycleListener() {
@Override
public void onStartup(final Container container) {
// access the ServiceLocator here
final ServiceLocator serviceLocator = container.getApplicationHandler().getInjectionManager().getInstance(ServiceLocator.class);
// Perform whatever with serviceLocator
}
@Override
public void onReload(final Container container) {
/* ... */}
@Override
public void onShutdown(final Container container) {
/* ... */}
});
第二种方法是使用Feature
,也可以使用@Provider
自动发现它:
@Provider
public final class StartupListener implements Feature {
private final ServiceLocator sl;
@Inject
public ProvisionStartupListener(final ServiceLocator sl) {
this.sl = sl;
}
@Override
public boolean configure(final FeatureContext context) {
// Perform whatever action with serviceLocator
return true;
}