net.sf.javagimmicks.cdi.CDIContext Maven / Gradle / Ivy
package net.sf.javagimmicks.cdi;
import java.lang.annotation.Annotation;
import javax.enterprise.inject.spi.AnnotatedType;
import javax.enterprise.inject.spi.Bean;
import javax.enterprise.inject.spi.BeanManager;
import javax.enterprise.inject.spi.CDI;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.InjectionTargetFactory;
import javax.inject.Named;
import javax.inject.Qualifier;
import javax.naming.InitialContext;
/**
* This is the central access point to the CDI {@link BeanManager} from non-CDI
* classes - also provides some simple bean lookup methods - use
* {@link InjectionSpec} for advanced lookups.
*/
public class CDIContext
{
/**
* The JNDI name that a {@link BeanManager} should have in a full-stack EE
* application server
*/
public static final String JNDI_FULL_EE = "java:comp/BeanManager";
/**
* The JNDI name that a {@link BeanManager} could have in some servlet
* containers (e.g. Tomcat)
*/
public static final String JNDI_SERVLET = "java:comp/env/BeanManager";
private static BeanManager _currentBeanManager;
private CDIContext()
{}
/**
* This method represents the core functionality of this class - it follows
* different strategies to get access to the CDI {@link BeanManager} instance
* and return it.
*
* These are the following:
*
* - Register a CDI {@link Extension} which intercepts CDI container
* startup and shutdown events and stores the so provided {@link BeanManager}
* internally for later use - this is sufficient in most cases and makes the
* other strategies nearly unnecessary
* - Try to get the {@link BeanManager} via the CDI API itself (call
* {@link CDI#current()} and then {@link CDI#getBeanManager()})
* - Try to lookup the {@link BeanManager} in JNDI with name
* {@link #JNDI_FULL_EE}
* - Try to lookup the {@link BeanManager} in JNDI with name
* {@link #JNDI_SERVLET}
*
*
* @return the current CDI {@link BeanManager} instance
* @throws IllegalStateException
* if no {@link BeanManager} could be found with any of the name
* strategies
*/
public static BeanManager getBeanManager()
{
if (_currentBeanManager != null)
{
synchronized (CDIContext.class)
{
if (_currentBeanManager != null)
{
return _currentBeanManager;
}
}
}
try
{
final BeanManager result = CDI.current().getBeanManager();
if (result != null)
{
return result;
}
}
catch (final Throwable t)
{
}
try
{
return (BeanManager) InitialContext.doLookup(JNDI_FULL_EE);
}
catch (final Throwable t)
{
}
try
{
return (BeanManager) InitialContext.doLookup(JNDI_SERVLET);
}
catch (final Throwable t)
{
}
throw new IllegalStateException("No BeanManager found!");
}
/**
* Looks up a bean of the given type and with the given {@link Qualifier}s
* within the CDI context.
*
* @param beanType
* the {@link Class} of the bean to lookup
* @param bindings
* the {@link Qualifier} annotations of the bean
* @param
* the type of the bean to lookup
* @return the resulting CDI bean
*/
public static E lookup(final Class beanType, final Annotation... bindings)
{
return InjectionSpec. build(getBeanManager()).setClass(beanType).addAnnotations(bindings).getInstance();
}
/**
* Looks up a bean of the given type within the CDI context.
*
* @param beanType
* the {@link Class} of the bean to lookup
* @param
* the type of the bean to lookup
* @return the resulting CDI bean
*/
public static E lookup(final Class beanType)
{
return lookup(beanType, new Annotation[0]);
}
/**
* Looks up a {@link Named} bean within the CDI context.
*
* @param name
* the name of the {@link Named} bean
* @param
* the type of the bean to lookup
* @return the resulting CDI bean
*/
public static E lookup(final String name)
{
return InjectionSpec. build(getBeanManager()).setName(name).getInstance();
}
/**
* Processes non-constructor injections and calls to post-construct methods
* on a given non-CDI bean.
*
* @param nonCdiObject
* a given bean that was not instantiated via CDI
* @param
* the type of the bean to initialize
* @return the bean itself after injections and post-constructs were
* performed
*/
@SuppressWarnings("unchecked")
public static T initBean(final T nonCdiObject)
{
final BeanManager beanManager = getBeanManager();
// Get all the object we need
final Bean bean = (Bean) beanManager.resolve(beanManager.getBeans(nonCdiObject.getClass()));
final AnnotatedType annotatedType = (AnnotatedType) beanManager
.createAnnotatedType(nonCdiObject.getClass());
InjectionTarget injectionTarget;
try
{
// CDI 1.1
final InjectionTargetFactory injectionTargetFactory = beanManager.getInjectionTargetFactory(annotatedType);
injectionTarget = injectionTargetFactory.createInjectionTarget(bean);
}
catch (final IncompatibleClassChangeError e)
{
// CDI 1.0
injectionTarget = beanManager.createInjectionTarget(annotatedType);
}
// Perform injections and run @PostConstruct
injectionTarget.inject(nonCdiObject, beanManager.createCreationalContext(bean));
injectionTarget.postConstruct(nonCdiObject);
return nonCdiObject;
}
static void setCurrentBeanManager(final BeanManager beanManager)
{
synchronized (CDIContext.class)
{
_currentBeanManager = beanManager;
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy