Neat. In fact the MapMaker[1] that takes a Function and provides
different eviction policies etc. that you used for the map of caches
will probably also save me from some manual work in the actual local
heap cache implementation around synchronization etc. Thanks!
Since I found it less than smooth to integrate Guice 3.0 in my maven
build at this point (Stuart McCulloch's snapshot build that was
discussed here seems to only have 2.1.8?), I replaced the
@AlwaysCreatesNewInstances with a simple @Named annotation to
differentiate the injection for the "actual cache factory" from the
Multiton giving me:
@Inject
public MultitonCacheFactory(@Named("underlyingFactory")
CacheFactory cacheFactory) {
this.underlyingFactory = cacheFactory;
}
And:
bind(CacheFactory.class).
to(MultitonCacheFactory.class).in(Singleton.class);
bind(CacheFactory.class).
annotatedWith(Names.named("underlyingFactory")).
toProvider( FactoryProvider.newFactory(CacheFactory.class,
NamedCacheLocal.class) );
This seems to work in the unit testing (and with some simple
concurrency testing). Any comments on that approach?
Will do a quick feasibility test, but cannot see why I should not be
able to wrap Coherence (or something similar) by just changing the
last of the two bindings.
-S-
[1] - This Google guava library was in fact all new to me and seems
really useful. Kudos goes to MV for releasing it under an Apache
license.
On Oct 14, 12:27 pm, Fred Faber <
ffa...@faiser.com> wrote:
> Basically you have a factory that should return a singleton instance for
> each unique string value passed into it?
>
> FactoryProvider won't do this for you out of the box, as it will create a
> new instance per invocation (as you've illustrated).
>
> What I would do in this case is to decorate your factory with an
> implementation that controls singletonness:
>
> interface CacheFactory {
> // This can be named anything you want, not just "create"
> NamedCache create(String name);
>
> }
>
> class CachingCacheFactory implements CacheFactory {
>
> private final CacheFactory underlyingFactory;
>
> //
http://guava-libraries.googlecode.com/svn/trunk/javadoc/com/google/co...
> private final Map<String, NamedCache> caches = new MapMaker()
> .makeComputingMap(new Function<String, NamedCache>(){
> @Override public NamedCache apply(String name) {
> return underlyingFactory.create(name);
> }
> });
>
> @Inject
> CachingCacheFactory {
> @AlwaysCreatesNewInstances CacheFactory cacheFactory) {
> this.underlyingFactory = cacheFactory;
> }
>
> @Override
> NamedCache create(String name) {
> return caches.get(name);
> }
>
> }
>
> * * *
>
> public class YourModule extends AbstractModule {
>
> @Override protected void configure() {
> // as an alternative to binding this as a singleton, you could inject
> the map of caches
> // as a singleton instance. 6 or 1/2 dozen, unless you want to
> unittest your
> // implementation, in which case you'll want to inject the singleton
> map
> bind(CacheFactory.class)
> .to(CachingCacheFactory.class)
> .in(Singleton.class);
>
> //
http://google-guice.googlecode.com/svn/trunk/javadoc/com/google/injec...
> // this binds a "CacheFactory" instance, annotated with
> @AlwaysCreatesNewInstances, to
> // a default factory implementation which will return instances of
> NamedCacheLocal when
> // its create() method is invoked
> install(new FactoryModuleBuilder()
> .implement(NamedCache, NamedCacheLocal)
> .build(Key.get(NamedCache.class,
> AlwaysCreatesNewInstances.class));
> }
>
> }
>
> That should do the trick.
>
> -Fred
>
> On Thu, Oct 14, 2010 at 4:25 AM, Sondre Bjornebekk <
>
> >
google-guice...@googlegroups.com<
google-guice%2Bunsu...@googlegroups.com>
> > .