DefaultSingletonBeanRegistry.java 3.4 KB
Newer Older
L
lancediarmuid 已提交
1 2 3 4
package cn.noexception.container.factory.support;

import cn.noexception.container.BeansException;
import cn.noexception.container.factory.DisposableBean;
5
import cn.noexception.container.factory.ObjectFactory;
L
lancediarmuid 已提交
6 7 8 9 10
import cn.noexception.container.factory.config.SingletonBeanRegistry;

import java.util.HashMap;
import java.util.Map;
import java.util.Set;
11
import java.util.concurrent.ConcurrentHashMap;
L
lancediarmuid 已提交
12 13 14 15 16 17 18 19

/**
 * DefaultSingletonBeanRegistry
 *
 * @author 吕滔
 * @Date 2021/10/22 17:35
 */
public class DefaultSingletonBeanRegistry implements SingletonBeanRegistry {
20 21 22 23 24 25 26 27 28
    // 一级缓存,存放普通对象
    private Map<String, Object> singletonObjects = new ConcurrentHashMap<>();

    // 二级缓存,提前暴露对象,即没有完全实例化的对象
    protected final Map<String, Object> earlySingletonObjects = new HashMap<>();

    // 三级缓存,存放代理对象
    private final Map<String, ObjectFactory<?>> singletonFactories = new HashMap<>();

L
lancediarmuid 已提交
29 30 31 32 33 34 35 36 37 38 39
    /**
     * 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();


    private final Map<String, DisposableBean> disposableBeans = new HashMap<>();

    @Override
    public Object getSingleton(String beanName) {
40 41 42
        Object singletonObject = singletonObjects.get(beanName);
        if (null == singletonObject) {
            singletonObject = earlySingletonObjects.get(beanName);
希川's avatar
希川 已提交
43
            // 判断二级缓存中是否有对象,这个对象就是代理对象,因为只有代理对象才会放到三级缓存中
44 45 46 47 48 49 50 51 52 53 54 55
            if (null == singletonObject) {
                ObjectFactory<?> singletonFactory = singletonFactories.get(beanName);

                if (singletonFactory != null) {
                    singletonObject = singletonFactory.getObject();
                    // 把三级缓存中的代理对象的真是对象获取出来,放入二级缓存中
                    earlySingletonObjects.put(beanName, singletonObject);
                    singletonFactories.remove(beanName);
                }
            }
        }
        return singletonObject;
L
lancediarmuid 已提交
56 57 58 59 60
    }

    @Override
    public void registerSingleton(String beanName, Object singletonObject) {
        singletonObjects.put(beanName, singletonObject);
61 62 63 64 65 66 67 68 69
        earlySingletonObjects.remove(beanName);
        singletonFactories.remove(beanName);
    }

    protected void addSingletonFactory(String beanName, ObjectFactory<?> singletonFactory) {
        if (!this.singletonObjects.containsKey(beanName)) {
            this.singletonFactories.put(beanName, singletonFactory);
            this.earlySingletonObjects.remove(beanName);
        }
L
lancediarmuid 已提交
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
    }

    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);
            }
        }
    }
}