package org.theonefx.wcframework.ioc;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.theonefx.wcframework.core.BeanDefinitionPostProcesser;
import org.theonefx.wcframework.utils.Assert;
class SingletonBeanFactory extends BeanDefinitionPostProcesser {
/**
* null的代替,为了解决ConcurrentHashMap不能存放null的问题
*/
protected static final Object NULL_OBJECT = new Object();
/**
* 缓存的单例对象map,用键值对的形式
*/
private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>();
/**
* 出于效率考虑,增加一个set按顺序存放所有单例对象的id
*/
private final Set<String> registeredSingletons = new LinkedHashSet<String>(16);
public void registerSingleton(String beanId, Object singletonObject) throws IllegalStateException {
Assert.notNull(beanId, "'beanId' 不能为空");
synchronized (this.singletonObjects) {
Object oldObject = this.singletonObjects.get(beanId);
if (oldObject != null) {
throw new IllegalStateException("无法使用 '" + beanId + "'注册对象 [" + singletonObject + "] : 对象已存在 [" + oldObject + "]");
}
addSingleton(beanId, singletonObject);
}
}
private void addSingleton(String beanName, Object singletonObject) {
synchronized (this.singletonObjects) {
this.singletonObjects.put(beanName, (singletonObject != null ? singletonObject : NULL_OBJECT));
this.registeredSingletons.add(beanName);
}
}
public Object getSingleton(String beanName) {
Object singletonObject = this.singletonObjects.get(beanName);
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
public Object getSingleton(String beanName, ObjectFactory<?> singletonFactory) {
Assert.notNull(beanName, "'beanName' 不能为空");
synchronized (this.singletonObjects) {
Object singletonObject = this.singletonObjects.get(beanName);
if (singletonObject == null) {
if (log.isDebugEnabled()) {
log.debug("创建共享的单例Bean:'" + beanName + "'");
}
singletonObject = singletonFactory.getObject();
addSingleton(beanName, singletonObject);
}
return (singletonObject != NULL_OBJECT ? singletonObject : null);
}
}
public boolean containsSingleton(String beanName) {
return (this.singletonObjects.containsKey(beanName));
}
protected final Object getSingletonObjectsMap() {
return this.singletonObjects;
}
}