スタンドアロンの Grizzly Web サーバーで Jersey 2 を使用しています。HK2 は CDI に使用されます。@PerLookup
-scope を jersey に注入したサービスを取得したいと思いContainerRequestFilter
ます。
サービス:
import org.glassfish.hk2.api.PerLookup;
import org.jvnet.hk2.annotations.Service;
@Service
@PerLookup
public class SessionManager {
[...]
}
フィルター:
import javax.annotation.Priority;
import javax.inject.Inject;
import javax.ws.rs.Priorities;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.container.PreMatching;
import javax.ws.rs.ext.Provider;
@Provider
@Priority(Priorities.AUTHENTICATION)
@PreMatching
public class HttpSessionFilter implements ContainerRequestFilter {
@Inject
private javax.inject.Provider<org.glassfish.grizzly.http.server.Request> requestProvider;
@Inject
private SessionManager sessionManager;
[...]
}
私の問題はこれです:
- フィルタは(起動時に)一度インスタンス化されます
- サービスは 1 回注入されます (フィルターの起動時)
- そこから下流のすべてがシングルトンスコープで効果的に起こっています
質問: リクエストごとにサービスを挿入するにはどうすればよいですか?
アップデート
使用する提案されたアプローチ@Inject javax.inject.Provider<SessionManager> sessionManagerProvider
は私には論理的に意味がありますが、 sessionManagerProvider.get()
null を返します。
hk2 serviceLocator は、inhabitant-generator によって設定されます。それは報告します:
SystemDescriptor(
implementation=com.skalio.skaliopush.http.SessionManager
contracts={com.skalio.skaliopush.http.SessionManager}
scope=org.glassfish.hk2.api.PerLookup
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=null
proxiable=null
proxyForSameScope=null
analysisName=null
id=31
locatorId=0
identityHashCode=494317290
reified=false)
また、明示的なバインディングを追加すると、次のようにも見つかります。
SystemDescriptor(
implementation=com.skalio.skaliopush.http.SessionManager
contracts={com.skalio.skaliopush.http.SessionManager}
scope=org.glassfish.jersey.process.internal.RequestScoped
qualifiers={}
descriptorType=CLASS
descriptorVisibility=NORMAL
metadata=
rank=0
loader=org.glassfish.hk2.utilities.binding.AbstractBinder$2@78b729e6
proxiable=null
proxyForSameScope=null
analysisName=null
id=39
locatorId=0
identityHashCode=2041416495
reified=false)
2回目の更新
私は 2 つのサービス ロケーターを使用しています。ジャージーが作成するもの。それらはBridgingInjectionResolverを介して結合されます。
Jerseyのサービスロケータに明示的なバインディングを追加すると、@peeskiletの応答が機能します。バインディングを他のサービス ロケーターに追加すると、上記の結果になります ( sessionManagerProvider.get()
null を返します)。