- ServletScopes.scopeRequest()はどのように使用されますか?
- Callable内の
@RequestScoped
オブジェクトへの参照を取得するにはどうすればよいですか? seedMap
のポイントは何ですか?それはデフォルトバインディングを上書きすることを意図していますか?- この方法とServletScopes.continueRequest()の違いは何ですか?
答えて
は自分の質問に答える:
- ServletScopes.scopeRequest()は新しいリクエストスコープで呼び出し可能実行されます。異なるスコープ間でオブジェクトを参照しないように注意してください。そうしないと、別の要求によって既に閉じられているデータベース接続を使用しようとするなど、スレッドの問題が発生します。
static
または最上位のクラスはあなたの友人です。 - に渡す前に
Callable
を注入してください。このため、あなたのCallable
に含まれるフィールドに注意する必要があります。もっと詳しくはこちら。 seedMap
を入力すると、スコープのないスコープにオブジェクトを挿入できます。これは危険ですので、注射するものには注意してください。- ServletScopes.continueRequest()は、の既存のリクエストスコープ内で実行される点を除いて同様です。現在のHTTPスコープのスナップショットを取得し、Callableでラップします。元のHTTPリクエストは完了します(サーバーからの応答が返されます)が、実際の操作は別のスレッドで非同期で完了します。 Callableが後で(別のスレッドで)呼び出されると、元のHttpServletRequestにアクセスできますが、HTTP応答やセッションにはアクセスできません。
これを行うにはどうすればよいですか?
あなたはCallable
にユーザーオブジェクトを渡す必要がない場合:要求の範囲外Callable
を注入し、ServletScopes.scopeRequest()にそれを渡します。 Callable
は、Foo
の代わりにProvider<Foo>
を参照するだけです。そうしないと、要求スコープ外にインスタンスが挿入されてしまいます。
ユーザーオブジェクトをCallable
に渡す必要がある場合は、をお読みください。
名前をデータベースに挿入するメソッドがあるとします。名前をCallable
に渡すには、2通りの方法があります。
は
InsertName
を定義し、データベースに挿入Callable
:@RequestScoped private static class InsertName implements Callable<Boolean> { private final String name; private final Connection connection; @Inject public InsertName(@Named("name") String name, Connection connection) { this.name = name; this.connection = connection; } @Override public Boolean call() { try { boolean nameAlreadyExists = ...; if (!nameAlreadyExists) { // insert the name return true; } return false; } finally { connection.close(); } } }
結合する全てのユーザオブジェクトで
アプローチ1:子モジュールを使用して渡し、ユーザオブジェクト子モジュールとRequestInjectorを使用して呼び出し可能範囲をスコープします。scopeRequest():
requestInjector.scopeRequest(InsertName.class, new AbstractModule() { @Override protected void configure() { bind(String.class).annotatedWith(Names.named("name")).toInstance("John"); } })
我々は要求外
RequestInjector
をインスタンス化し、それが、今度は、要求内側第Callable
を注入します。 2番目のCallable
は、リクエストスコープの内側に挿入されているため、Foo
を直接参照できます(プロバイダーは不要です)。
import com.google.common.base.Preconditions;
import com.google.inject.Inject;
import com.google.inject.Injector;
import com.google.inject.Key;
import com.google.inject.Module;
import com.google.inject.servlet.ServletScopes;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.Callable;
/**
* Injects a Callable into a non-HTTP request scope.
* <p/>
* @author Gili Tzabari
*/
public final class RequestInjector
{
private final Map<Key<?>, Object> seedMap = Collections.emptyMap();
private final Injector injector;
/**
* Creates a new RequestInjector.
*/
@Inject
private RequestInjector(Injector injector)
{
this.injector = injector;
}
/**
* Scopes a Callable in a non-HTTP request scope.
* <p/>
* @param <V> the type of object returned by the Callable
* @param callable the class to inject and execute in the request scope
* @param modules additional modules to install into the request scope
* @return a wrapper that invokes delegate in the request scope
*/
public <V> Callable<V> scopeRequest(final Class<? extends Callable<V>> callable,
final Module... modules)
{
Preconditions.checkNotNull(callable, "callable may not be null");
return ServletScopes.scopeRequest(new Callable<V>()
{
@Override
public V call() throws Exception
{
return injector.createChildInjector(modules).getInstance(callable).call();
}
}, seedMap);
}
}
アプローチ2:Provider<Foo>
を参照要求外側Callable
を注入。 call()
メソッドは、get()
の要求スコープ内の実際の値になります。オブジェクトオブジェクトは、(私は個人的にこのアプローチを反直感的に見つける)seedMap
の仕方によって渡されます。
は、データベースに挿入
Callable
をInsertName
を定義します。アプローチ1とは異なり、我々はProviders
を使用しなければならないことに注意してください:。@RequestScoped private static class InsertName implements Callable<Boolean> { private final Provider<String> name; private final Provider<Connection> connection; @Inject public InsertName(@Named("name") Provider<String> name, Provider<Connection> connection) { this.name = name; this.connection = connection; } @Override public Boolean call() { try { boolean nameAlreadyExists = ...; if (!nameAlreadyExists) { // insert the name return true; } return false; } finally { connection.close(); } } }
は、そうしないとあなたが得るあなたに渡したいタイプのための偽のバインディングを作成します。これが必要な理由
No implementation for String annotated with @com.google.inject.name.Named(value=name) was bound.
https://stackoverflow.com/a/9014552/14731は説明しています。所望の値とseedMap移入:
ImmutableMap<Key<?>, Object> seedMap = ImmutableMap.<Key<?>, Object>of(Key.get(String.class, Names.named("name")), "john");
起動
ServletScopes.scopeRequest()
:ServletScopes.scopeRequest(injector.getInstance(InsertName.class), seedMap);
を
- 1. Webアプリケーションでのインターセプタの使用方法と使用方法
- 2. onSaveInstanceState()とonRestoreInstanceState()の使用方法は?
- 3. ツールバーとScrollViewの使用方法は?
- 4. AC_CONFIG_COMMANDS_PREとAC_CONFIG_COMMANDS_POSTの使用方法は?
- 5. ParcelableとonClickListenersの使用方法は?
- 6. grunt-UglifyJSとソースマップの使用方法は?
- 7. QNameとOperatorクラスの使用方法は?
- 8. デリゲートとイベントの使用方法は?
- 9. ICUとFreetypeの使用方法は?
- 10. .CSProjと.Slnファイルの使用方法は?
- 11. アルゴリズムの保存と使用方法は?
- 12. setCellValueFactoryとsetCellFactoryの使用方法は?
- 13. FluentValidation.AspNetCoreとFluentValidation.MVC6の使用方法は?
- 14. 継続継承スタイルの使用方法と使用方法
- 15. std :: unique_ptrの宣言方法とその使用方法は?
- 16. OWIN JWTの作成方法と使用方法は?
- 17. デリゲートの使用方法は? (WPF Storyboardsを例として使用)
- 18. imap_searchで 'ALL'を使用する方法と使用方法
- 19. 遅延ジョブ:使用方法と使用方法
- 20. BottomSheetDialog/BottomSheetDialogFragment - 使用する方法とは?
- 21. 使用方法は
- 22. キュウリとguiceとロンボクの使用方法
- 23. pygame.surface.scroll()の使用方法は?
- 24. ClojureScriptの使用方法は?
- 25. navigator.app.exitApp()の使用方法は?
- 26. ストアドプロシージャの使用方法は?
- 27. dispatchTouchEventの使用方法は?
- 28. __RequestVerificationTokenの使用方法は?
- 29. AuthorizationServerSecurityConfigurerの使用方法は?
- 30. AngularJS $の使用方法は?