前面章节 请参看tiny-spring或者小傅哥的small-spring
代码变更对比图
解析
实例1:类似死锁,一个类A实例化对象的时候,A对象的属性包含一个类B的对象;
public class CircleTest {
private final static Map<String, Object> singletonObjects = new ConcurrentHashMap<>(256);
public static void main(String[] args) throws Exception {
System.out.println(getBean(B.class).getA());
System.out.println(getBean(A.class).getB());
}
private static <T> T getBean(Class<T> beanClass) throws Exception {
String beanName = beanClass.getSimpleName().toLowerCase();
if (singletonObjects.containsKey(beanName)) {
return (T) singletonObjects.get(beanName);
}
// 实例化对象入缓存
Object obj = beanClass.newInstance();
singletonObjects.put(beanName, obj);
// 属性填充补全对象
Field[] fields = obj.getClass().getDeclaredFields();
for (Field field : fields) {
field.setAccessible(true);
Class<?> fieldClass = field.getType();
String fieldBeanName = fieldClass.getSimpleName().toLowerCase();
field.set(obj, singletonObjects.containsKey(fieldBeanName) ? singletonObjects.get(fieldBeanName) : getBean(fieldClass));
field.setAccessible(false);
}
return (T) obj;
}
}
class A {
private B b;
public B getB() {
return b;
}
public void setB(B b) {
this.b = b;
}
}
class B {
private A a;
public A getA() {
return a;
}
public void setA(A a) {
this.a = a;
}
}
通过缓存我们先把实例化好的但是没有赋值属性的对象放入缓存,
然后再设置属性的时候通过缓存这个“中间人”来达到处理循环依赖的问题。
构造器注入Spring也不能解决
源码分析
/**
*
*/
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
/**
* Internal marker for a null singleton object:
* used as marker value for concurrent Maps (which don't support null values).
*/
protected static final Object NULL_OBJECT = new Object();
/**
* 一级缓存,普通对象
* Cache of sinleton Objects:bean Name --> bean Instance
*/
private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();
/**
* 二级缓存, 提前暴露对象,没有完全实例化的对象
* Cache of early sinleton objects: bean name --> bean instance
*/
private final Map<String, Object> earlySinletonObjects = new HashMap<>();
/**
* 三级缓存, 存放的代理对象
* Cache of sinleton fatories: bean name --> ObjectFactory
*/
private final Map<String, ObjectFatory<?>> sinletonFactories = new HashMap<>();
private final Map<String, DisposableBean> disposableBeans = new LinkedHashMap<>();
/**
* 获取单例对象:
* 1、从一级缓存拿
* 2、一级缓存卫康:去二级缓存拿
* 3、二级缓存为空:去三级缓存拿
* 4、三级缓存如有:拿出来并放入二级缓存,并在三级缓存remove这个单例
* 5、返回实例
*/
@Override
public Object getSingleton(String beanName) {
Object singletonObject = singletonObjects.get(beanName);
if (singletonObject == null) {
singletonObject = earlySinletonObjects.get(beanName);
if (singletonObject == null) {
ObjectFatory<?> sinletonFactory = sinletonFactories.get(beanName);
if (sinletonFactory != null) {
singletonObject = sinletonFactory.getObject();
earlySinletonObjects.put(beanName, singletonObject);
sinletonFactories.remove(beanName);
}
}
}
return singletonObject;
}
/**
* 注册单例对象:
* 1、放入一级缓存
* 2、清空二级缓存
* 3、清空三级缓存
*/
public void registerSingleton(String beanName, Object singletonObject) {
singletonObjects.put(beanName, singletonObject);
earlySinletonObjects.remove(beanName);
sinletonFactories.remove(beanName);
}
protected void addSingletonFactory(String beanName, ObjectFatory<?> sinletonFactory) {
if (!this.singletonObjects.containsKey(beanName)) {
this.sinletonFactories.put(beanName, sinletonFactory);
this.earlySinletonObjects.remove(beanName);
}
}
public void registerDisposableBean(String beanName, DisposableBean bean) {
disposableBeans.put(beanName, bean);
}
public void destroySingletons() {
Set<String> keySet = this.disposableBeans.keySet();
Object[] disposableBeanNames = keySet.toArray();
for (int i = disposableBeanNames.length - 1; i >= 0; i--) {
Object beanName = disposableBeanNames[i];
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);
}
}
}
先注意看我们的默认单例bean注册器实现类DefaultSingletonBeanRegistry ,
他里面就通过三个map分别实现了三个缓存,也就是三级缓存:
singletonObjects、earlySinletonObjects、sinletonFactories
- singletonObjects一级保存完整的单例bean;
- earlySinletonObjects二级缓存未完全实例化赋值属性的bean;
- sinletonFactories三级处理的就是AOP对象,为了避免重复生成新的AOP对象违背单例的设计。