- How is one supposed to use ServletScopes.scopeRequest()?
- How do I get a reference to a
@RequestScopedobject inside the Callable? - What’s the point of
seedMap? Is it meant to override the default binding? - What’s the difference between this method and ServletScopes.continueRequest()?
How is one supposed to use ServletScopes.scopeRequest() ? How do I get a reference
Share
Answering my own question:
staticor top-level classes are your friend here.Callablebefore passing it into ServletScopes.scopeRequest(). For this reason, you must be careful what fields yourCallablecontains. More on this below.seedMapallows you to inject non-scoped objects into the scope. This is dangerous so be careful with what you inject.So, what’s the best way to do this?
If you don’t need to pass user-objects into the
Callable: Inject theCallableoutside the request scope, and pass it into ServletScopes.scopeRequest(). TheCallablemay only referenceProvider<Foo>instead ofFoo, otherwise you’ll end up with instances injected outside of the request scope.If you need to pass user-objects into the
Callable, read on.Say you have a method that inserts names into a database. There are two ways for us to pass the name into the
Callable.Approach 1: Pass user-objects using a child module:
Define
InsertName, aCallablethat inserts into the database:Bind all user-objects in a child module and scope the callable using RequestInjector.scopeRequest():
We instantiate a
RequestInjectoroutside the request and it, in turn, injects a secondCallableinside the request. The secondCallablecan referenceFoodirectly (no need for Providers) because it’s injected inside the request scope.Approach 2: Inject a
Callableoutside the request that referencesProvider<Foo>. Thecall()method can thenget()the actual values inside the request scope. The object objects are passed in by way of aseedMap(I personally find this approach counter-intuitive):Define
InsertName, aCallablethat inserts into the database. Notice that unlike Approach 1, we must useProviders:Create bogus bindings for the types you want to pass in. If you don’t you will get:
No implementation for String annotated with @com.google.inject.name.Named(value=name) was bound.https://stackoverflow.com/a/9014552/14731 explains why this is needed.Populate the seedMap with the desired values:
Invoke
ServletScopes.scopeRequest():