spring的Singleton获取实现如下:
首先实现最基础的singleton基础接口
public interface SingletonBeanRegistry {
Object getSingleton(String beanName);
void addSingleton(String beanName, Object SingletonObject);
}
定义bean容器接口
package org.springframework.beans.factory;
public interface BeanFactory {
Object getBean(String name) throws BeansException;
/**
* 根据名称和类型查找bean
*
* @param name
* @param requiredType
* @param <T>
* @return
* @throws BeansException
*/
<T> T getBean(String name, Class<T> requiredType) throws BeansException;
<T> T getBean(Class<T> requiredType) throws BeansException;
boolean containsBean(String name);
}
定义singleton三级缓存
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
private Map<String, Object> singletonObjects = new HashMap<>();
private Map<String, Object> earlySingletonObjects = new HashMap<>();
private Map<String, ObjectFactory<?>> singletonFactorys = new HashMap<String, ObjectFactory<?>>();
//用于销毁
private final Map<String, DisposableBean> disposableBeans = new HashMap<>();
@Override
public Object getSingleton(String beanName) {
Object singletonObject = singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = earlySingletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFactory<?> objectFactory = singletonFactorys.get(beanName);
if (objectFactory != null) {
singletonObject = objectFactory.getObject();
earlySingletonObjects.put(beanName, singletonObject);
singletonFactorys.remove(singletonObject);
}
}
}
return singletonObject;
}
@Override
public void addSingleton(String beanName, Object singletonObject) {
singletonObjects.put(beanName, singletonObject);
earlySingletonObjects.remove(beanName);
singletonFactorys.remove(beanName);
}
protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
singletonFactorys.put(beanName, singletonFactory);
}
public void registerDisposableBean(String beanName, DisposableBean bean) {
disposableBeans.put(beanName, bean);
}
public void destroySingletons() {
ArrayList<String> beanNames = new ArrayList<>(disposableBeans.keySet());
for (String beanName : beanNames) {
DisposableBean disposableBean = disposableBeans.remove(beanName);
try {
disposableBean.destroy();
} catch (Exception e) {
throw new BeansException("Destroy method on bean with name '" + beanName + "' threw an exception", e);
}
}
}
}