Created
August 28, 2012 15:51
-
-
Save pmuir/3499355 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class NonContextualInjector<T> { | |
// Store the injection target. The CDI spec doesn't require an implementation to cache it, so we do | |
private final InjectionTarget<T> injectionTarget; | |
// Store a reference to the CDI BeanManager | |
private final BeanManager beanManager; | |
/** | |
* Create an injector for the given class | |
*/ | |
public NonContextual(BeanManager manager, Class<T> clazz) { | |
this.beanManager = manager; | |
// Generate an "Annotated Type" | |
AnnotatedType<T> type = manager.createAnnotatedType(clazz); | |
// Generate the InjectionTarget | |
this.injectionTarget = manager.createInjectionTarget(type); | |
} | |
/** | |
* Create an injector for the given class | |
*/ | |
public NonContextual(BeanManager manager, AnnotatedType<T> type) { | |
this.beanManager = manager; | |
// Generate the InjectionTarget | |
this.injectionTarget = manager.createInjectionTarget(type); | |
} | |
/** | |
* Create an injector for the given class | |
*/ | |
public NonContextual(Class<T> clazz) { | |
this.beanManager = CDI.current().getBeanManager(); | |
// Generate an "Annotated Type" | |
AnnotatedType<T> type = manager.createAnnotatedType(clazz); | |
// Generate the InjectionTarget | |
this.injectionTarget = manager.createInjectionTarget(type); | |
} | |
/** | |
* Create an injector for the given class | |
*/ | |
public NonContextual(AnnotatedType<T> type) { | |
this.beanManager = CDI.current().getBeanManager(); | |
// Generate the InjectionTarget | |
this.injectionTarget = manager.createInjectionTarget(type); | |
} | |
public Instance<T> newInstance() { | |
return new Instance<T>(beanManager, injectionTarget); | |
} | |
/** | |
* Represents a non-contextual instance | |
*/ | |
public static class Instance<T> | |
{ | |
private final CreationalContext<T> ctx; | |
private final InjectionTarget<T> injectionTarget; | |
private T instance; | |
private boolean disposed = false; | |
private Instance(BeanManager beanManager, InjectionTarget<T> injectionTarget) { | |
this.injectionTarget = injectionTarget; | |
this.ctx = beanManager.createCreationalContext(null); | |
} | |
/** | |
* Get the instance | |
*/ | |
public T get() { | |
if (disposed) { | |
throw new IllegalStateException("Trying to call get() on an already disposed instance"); | |
} | |
if (this.instance == null) { | |
produce(); | |
inject(); | |
postConstruct(); | |
} | |
return instance; | |
} | |
public void destroy() { | |
if (this.instance == null) { | |
throw new IllegalStateException("Trying to call destroy() before the instance was created was called"); | |
} | |
if (disposed) { | |
throw new IllegalStateException("Trying to call destroy() on already disposed instance"); | |
} | |
preDestroy(); | |
dispose(); | |
} | |
/** | |
* Create the instance | |
*/ | |
public Instance<T> produce() { | |
if (this.instance != null) { | |
throw new IllegalStateException("Trying to call produce() on already constructed instance"); | |
} | |
if (disposed) { | |
throw new IllegalStateException("Trying to call produce() on an already disposed instance"); | |
} | |
this.instance = injectionTarget.produce(ctx); | |
return this; | |
} | |
/** | |
* Inject the instance | |
*/ | |
public Instance<T> inject() { | |
if (this.instance == null) { | |
throw new IllegalStateException("Trying to call inject() before produce() was called"); | |
} | |
if (disposed) { | |
throw new IllegalStateException("Trying to call inject() on already disposed instance"); | |
} | |
injectionTarget.inject(instance, ctx); | |
return this; | |
} | |
/** | |
* Call the @PostConstruct callback | |
*/ | |
public Instance<T> postConstruct() { | |
if (this.instance == null) { | |
throw new IllegalStateException("Trying to call postConstruct() before produce() was called"); | |
} | |
if (disposed) { | |
throw new IllegalStateException("Trying to call preDestroy() on already disposed instance"); | |
} | |
injectionTarget.postConstruct(instance); | |
return this; | |
} | |
/** | |
* Call the @PreDestroy callback | |
*/ | |
public Instance<T> preDestroy() { | |
if (this.instance == null) { | |
throw new IllegalStateException("Trying to call preDestroy() before produce() was called"); | |
} | |
if (disposed) { | |
throw new IllegalStateException("Trying to call preDestroy() on already disposed instance"); | |
} | |
injectionTarget.preDestroy(instance); | |
return this; | |
} | |
/** | |
* Dispose of the instance, doing any necessary cleanup | |
*/ | |
public Instance<T> dispose() { | |
if (this.instance == null) { | |
throw new IllegalStateException("Trying to call dispose() before produce() was called"); | |
} | |
if (disposed) { | |
throw new IllegalStateException("Trying to call dispose() on already disposed instance"); | |
} | |
injectionTarget.dispose(instance); | |
ctx.release(); | |
return this; | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment