0

スタンドアロンの 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 を返します)。

4

1 に答える 1

0

も使用すると機能するはずですjavax.inject.Provider<SessionMananger>。デフォルトのスコープはルックアップごとです。しかし、遅延ロードする必要があると思います。

RequestScopedジャージーと機能的にどのように違うのかわかりません。PerLookupスコープ内で、フィルタに 1 回、リソース クラスに 1 回注入すると 2 回作成されると思っていましたが、今テストしたところ、PerLookupスコープ内でも、リクエストごとに 1 回しか作成されませんでした。

または、念のため、それRequestScopedが本当に必要な場合は、バインドすることもできます。

register(new AbstractBinder(){
    protected void configure() {
        bind(SessionManager.class).to(SessionManager.class)
                                  .in(RequestScoped.class);
    }
});
于 2015-09-15T16:24:09.157 に答える