Skip to content

Commit

Permalink
implemented webapp friendly singleton
Browse files Browse the repository at this point in the history
  • Loading branch information
cdiadvocate committed Apr 26, 2011
1 parent a43da92 commit 7aeeb6f
Show file tree
Hide file tree
Showing 19 changed files with 187 additions and 120 deletions.
Expand Up @@ -186,5 +186,13 @@ protected BeanNamespace buildNamespaceLookup() {
* particular CDI implementation.
*/
protected abstract void doStop();

@Override
public void startScope(Class<?> scope) {
}

@Override
public void stopScope(Class<?> scope) {
}

}
Expand Up @@ -79,6 +79,10 @@ public interface BeanContainer {
* beans.
*/
public BeanNamespace getBeanNamespace();


public void startScope(Class<?> scope);
public void stopScope(Class<?> scope);



Expand Down
@@ -1,6 +1,5 @@
package org.cdisource.beancontainer;

//import javax.enterprise.context.spi.Context;
import javax.enterprise.inject.spi.BeanManager;
import javax.inject.Inject;

Expand Down Expand Up @@ -33,4 +32,5 @@ protected void doStart() throws Exception {
protected void doStop() {
}


}
Expand Up @@ -2,9 +2,12 @@

import java.lang.annotation.Annotation;

import javax.enterprise.context.RequestScoped;
import javax.enterprise.context.spi.Context;
import javax.enterprise.inject.spi.BeanManager;

import com.caucho.resin.BeanContainerRequest;

public class ResinBeanContainer extends AbstractBeanContainer {

public Context getContextByScope(Class<? extends Annotation> scopeType){
Expand Down Expand Up @@ -37,5 +40,27 @@ protected void doStart() throws Exception {
protected void doStop() {
delegate.close();
}

ThreadLocal<BeanContainerRequest> requestScopeHolder = new ThreadLocal<BeanContainerRequest>();
@Override
public void startScope(Class<?> scope) {
if (scope == RequestScoped.class) {
BeanContainerRequest beginRequest = delegate.beginRequest();
requestScopeHolder.set(beginRequest);
}else {
//...
}
}

@Override
public void stopScope(Class<?> scope) {
if (scope == RequestScoped.class) {
requestScopeHolder.set(null);
} else {
//...
}

}


}
Expand Up @@ -4,61 +4,33 @@
import javax.naming.InitialContext;

import org.cdisource.beancontainer.BeanContainer;
import org.cdisource.beancontainer.BeanContainerInitializationException;
import org.cdisource.beancontainer.BeanContainerManager;
import org.cdisource.beancontainer.BeanManagerLocator;

public class BeanManagerLocationUtil {

private final String BEAN_MANAGER_LOCATION = "java:comp/BeanManager";
private BeanManager beanManager;
private boolean useJNDI = true;

public void setUseJNDI(boolean useJNDI) {
this.useJNDI = useJNDI;
}


BeanManager beanManager() {

if (lookupInJNDI()==null) {
BeanContainer beanContainer = BeanContainerManager.createInstance();
beanContainer.start();
return( (BeanManagerLocator)beanContainer).getBeanManager();
} else {
return this.beanManager;
}

if (lookupInJNDI() == null) {
BeanContainer beanContainer = BeanContainerManager.getInstance();
return ((BeanManagerLocator) beanContainer).getBeanManager();
} else {
return this.beanManager;
}
}

private BeanManager lookupInJNDI() {
if (useJNDI==false) {
return null;
}
if (beanManager == null) {
Object bean = null;

try {
InitialContext ic = new InitialContext();
bean = ic.lookup(BEAN_MANAGER_LOCATION);
return (BeanManager) ic.lookup(BEAN_MANAGER_LOCATION);
} catch (Exception e) {
throw new BeanContainerInitializationException(
"Unable to lookup BeanManager instance in JNDI", e);
}
if (bean == null) {
throw new BeanContainerInitializationException(
"Null value returned when looking up the BeanManager from JNDI");
}
if (bean instanceof BeanManager) {
this.beanManager = (BeanManager) bean;
} else {
String msg = "Looked up JNDI Bean is not a BeanManager instance, bean type is "
+ bean.getClass().getName();
throw new BeanContainerInitializationException(msg);
return null;
}
}
return this.beanManager;
}


}
Expand Up @@ -42,13 +42,11 @@ public String[] getBeanDefinitionNames() {
@SuppressWarnings({ "unchecked", "rawtypes" })
@Override
public Object getBean(String name, Class requiredType, Object... args) {
System.out.println("######################### CALLED????" + name + "required type " + requiredType);
return beanContainer().getBeanByName(requiredType, name);
}

@Override
public <T> T getBean(Class<T> type) {
System.out.println("########################### CALLED getBean " + type);
return beanContainer().getBeanByType(type);
}

Expand Down
Expand Up @@ -11,19 +11,11 @@
import org.springframework.beans.factory.support.DefaultListableBeanFactory;


//TODO figure out if the bean is coming from CDI or Spring or not
public class CdiBeanFactoryPostProcessor implements BeanFactoryPostProcessor {

private boolean useLongName;

private BeanManagerLocationUtil beanManagerLocationUtil = new BeanManagerLocationUtil();
private boolean useJNDI = true;


public void setUseJNDI(boolean useJNDI) {
this.beanManagerLocationUtil.setUseJNDI(useJNDI);
this.useJNDI = useJNDI;
}


@Override
Expand All @@ -43,7 +35,6 @@ public void postProcessBeanFactory(
}
BeanDefinitionBuilder definition = BeanDefinitionBuilder.rootBeanDefinition(CdiFactoryBean.class)
.addPropertyValue("beanClass", bean.getBeanClass())
.addPropertyValue("useJNDI", this.useJNDI)
.setLazyInit(true);
String name = generateName(bean);
factory.registerBeanDefinition(name, definition.getBeanDefinition());
Expand Down
Expand Up @@ -12,12 +12,6 @@ public class CdiFactoryBean implements FactoryBean<Object> {
private boolean singleton = true;


public void setUseJNDI(boolean useJNDI) {
this.beanManagerLocationUtil.setUseJNDI(useJNDI);
}



public void setBeanClass(Class<?> beanClass) {
this.beanClass = beanClass;
}
Expand Down
Expand Up @@ -10,4 +10,5 @@ public class SpringBridge {
// System.out.println("Name of Spring object " + spring.name());
// return new TaskValidator();
// }

}
Expand Up @@ -17,7 +17,6 @@
import javax.enterprise.inject.spi.BeforeBeanDiscovery;
import javax.enterprise.inject.spi.Extension;
import javax.enterprise.inject.spi.InjectionPoint;
import javax.enterprise.inject.spi.InjectionTarget;
import javax.enterprise.inject.spi.ProcessInjectionTarget;
import javax.enterprise.util.AnnotationLiteral;
import javax.enterprise.context.Dependent;
Expand All @@ -42,9 +41,6 @@ public void processInjectionTarget (@Observes ProcessInjectionTarget<?> pit, Bea
continue;
}

//TODO add springBeans.contains so I can check before creating if I need to create
//this means externalizing the key gen into a helper method

Class<?> injectionType = (Class<?>) point.getType();
Spring spring = point.getAnnotated().getAnnotation(Spring.class);
if (spring!=null) {
Expand Down Expand Up @@ -86,32 +82,26 @@ class SpringBean implements Bean <Object> {

AnnotatedType<?> annotatedType;

@SuppressWarnings({ "rawtypes", "unchecked" })
SpringBean(AnnotatedType<?> annotatedType, Spring spring, Class<?> injectionType, BeanManager bm){
this.spring = spring;
this.injectionType = injectionType;
this.bm = bm;
AnnotatedType at = bm.createAnnotatedType(injectionType);
this.annotatedType = annotatedType;
//it = bm.createInjectionTarget(at);
}

@SuppressWarnings({ "rawtypes", "unchecked" })
public SpringBean(SpringLookup springLookup, Class<?> type,
BeanManager bm) {
this.lookup = springLookup;
this.injectionType = type;
this.bm = bm;
AnnotatedType at = bm.createAnnotatedType(injectionType);
//it = bm.createInjectionTarget(at);

}

public String key () {
return "" + this.getName() + "::" + injectionType.toString();
}

@SuppressWarnings("serial")
@SuppressWarnings("all")
class NamedLiteral extends AnnotationLiteral<Named> implements Named {

@Override
Expand Down Expand Up @@ -182,6 +172,11 @@ public boolean isNullable() {
public Object create(CreationalContext<Object> ctx) {
ApplicationContext applicationContext = ApplicationContextLocatorManager.getInstance().locateApplicationContext();
if (applicationContext==null) {
if (spring !=null) {
System.err.printf("############## spring name=%s type=%s \n\n\n", spring.name(), spring.type());
} else {
System.err.printf("############## lookup value=%s \n\n\n", lookup.value());
}
throw new IllegalStateException("applicationContext was null");
}
Object instance = null;
Expand All @@ -200,20 +195,16 @@ public Object create(CreationalContext<Object> ctx) {
} else {
instance = applicationContext.getBean(lookup.value());
}
//it.inject(instance, ctx);
//it.postConstruct(instance);
return instance;
}

@Override
public void destroy(Object instance, CreationalContext<Object> ctx) {
//it.preDestroy(instance);
//it.dispose(instance);
ctx.release();
}

public String toString() {
return "SpringBean(annotatedType="+ annotatedType.toString() +"key=" + this.key() +")";
return String.format("SpringBean(hc=%d, hc=%d, annotatedType=%s, qualifiers=%s)", this.hashCode(), SpringIntegrationExtention.this.hashCode(), this.annotatedType, this.getQualifiers() );
}

}
Expand Down
Expand Up @@ -6,7 +6,9 @@
import java.util.Map;
import java.util.WeakHashMap;

import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;


/** Simple implementation of the ApplicationContextLocator that is web application friendly.
Expand All @@ -17,25 +19,56 @@
*/
public class ApplicationContextLocatorImpl implements ApplicationContextLocator{

public static Map<ClassLoader, WeakReference<ApplicationContext>> map =
private static Map<ClassLoader, WeakReference<ApplicationContext>> map =
Collections.synchronizedMap(new WeakHashMap<ClassLoader, WeakReference<ApplicationContext>>());

public static void putContext(ApplicationContext context) {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();
map.put(contextClassLoader, new WeakReference<ApplicationContext>(context));
}

public ApplicationContextLocatorImpl() {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

WeakReference<ApplicationContext> reference = map.get(contextClassLoader);

/* To prevent GC from killing this until web app is gone.
*/
ApplicationContext applicationContext;

if (reference==null) {
throw new IllegalStateException("1: Applicaiton context must be associated with the current classloader first");
} else {
applicationContext = reference.get();
}

if (applicationContext!=null) {
String beanName = ApplicationContextLocator.class.getName();
if (!applicationContext.containsBean(beanName)) {
ConfigurableListableBeanFactory beanFactory = ((ConfigurableApplicationContext)applicationContext).getBeanFactory();
beanFactory.registerSingleton(beanName, this);
}
} else {
throw new IllegalStateException("1: Applicaiton context must be associated with the current classloader first");
}

}

@Override
public ApplicationContext locateApplicationContext() {
ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();

WeakReference<ApplicationContext> reference = map.get(contextClassLoader);

ApplicationContext applicationContext;

if (reference==null) {
return null;
} else {
return reference.get();
applicationContext = reference.get();
}


return applicationContext;
}

}

0 comments on commit 7aeeb6f

Please sign in to comment.