All Downloads are FREE. Search and download functionalities are using the official Maven repository.

commons.box.app.SObjectFactory Maven / Gradle / Ivy

The newest version!
package commons.box.app;

import commons.box.app.func.DataFunction;
import commons.box.util.Collects;
import commons.box.util.Logs;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;

/**
 * 单例模式对象工厂
 */
public class SObjectFactory {
    private static final AppLog LOG = Logs.get(SObjectFactory.class);
    protected final Map> objects = new SafeMap<>();

    public SObjectFactory() {
    }

    protected SObjectFactory(Map> objects) {
        if (objects != null) this.objects.putAll(objects);
    }

    /**
     * 是否包含对象
     *
     * @param name
     * @return
     */
    public boolean has(K name) {
        if (name == null) return false;
        return this.objects.containsKey(name);
    }

    public Set names() {
        return Collects.immset(this.objects.keySet());
    }

    public List values() {
        List values = new ArrayList<>();
        for (SObject vo : this.objects.values()) if (vo != null && vo.raw() != null) values.add(vo.raw());
        return Collects.immlist(values);
    }

    /**
     * 增加provider
     *
     * @param name
     * @param provider
     */
    public void provider(K name, DataFunction provider) {
        if (name == null) return;
        synchronized (this.objects) {
            if (provider == null) this.objects.remove(name);
            else {
                SObject sno = new SObject<>(() -> provider.apply(name));
                //TODO 当前逻辑是直接替换已有声明,考虑是否需要迁移原有值
                //SObject so = this.objects.get(name);
                //if (so != null && so.raw() != null) sno.set(so.raw());
                this.objects.put(name, sno);
            }
        }
    }

    public void add(K name, V object, boolean overwrite) {
        if (name == null || object == null) return;
        synchronized (this.objects) { // TODO 验证此处保持同步是否影响性能
            SObject so = this.objects.get(name);
            if (so == null) {
                so = new SObject<>(object);
                this.objects.put(name, so);
            } else if (overwrite) so.set(object);
        }
    }

    /**
     * 直接获取内部对象 不存在时直接返回空
     *
     * @param name
     * @param 
     * @return
     */
    @SuppressWarnings("unchecked")
    public  T raw(final K name) {
        SObject ov = this.objects.get(name);
        if (ov == null) return null;
        return (T) ov.raw();
    }

    /**
     * 获取单例对象 指定对象类型 如果对象不存在则使用给定的provider获取目标对象
     *
     * @param name
     * @param type
     * @param provider
     * @return
     */
    public  T get(final K name, final Class type, final DataFunction provider) {
        T obj = this.innerGet(name, provider);
        if (obj == null) return null;
        if (type != null) {
            if (type.isInstance(obj)) return obj;
            throw new ClassCastException("生成的对象不兼容类型 " + type.getName());
        }

        return obj;
    }

    public  T get(final K name, final Class type) {
        return this.get(name, type, null);
    }


    /**
     * 获取单例对象 如果对象不存在则使用给定的provider获取目标对象
     *
     * @param name
     * @param provider
     * @return
     */
    public  T get(final K name, final DataFunction provider) {
        return this.innerGet(name, provider);
    }

    /**
     * 为了避免 lambda 非静态引用,本方法提供了一个机制:通过 context 注入参数计算 key 和对应的 provider
     * 

* 注意,当 provider 引用了 context 时,需确保 context-keyFunc-provider 对于相同 keyFunc 返回值应返回相同的 provider 结果 *

* 本方法使用时,keyFunc / provider 应该是statless的(不应引用额外的外部变量和字段)。 * * @param context * @param keyFunc * @param provider * @param * @param * @return */ public final T doGet(final C context, DataFunction keyFunc, DataFunction provider) { if (keyFunc == null) return null; return innerDoGet(context, keyFunc.apply(context), provider); } /** * 载入单例对象 * * @param name * @param provider * @return */ private T innerGet(K name, DataFunction provider) { if (name == null) return null; return innerDoGet(name, name, provider); } @SuppressWarnings("unchecked") private T innerDoGet(final C context, K name, DataFunction provider) { if (name == null) return null; SObject obj = this.objects.get(name); if (obj == null) { synchronized (this.objects) { obj = this.objects.get(name); if (obj == null) { obj = new SObject<>(() -> (provider != null) ? provider.apply(context) : null); this.objects.put(name, obj); } } } return (T) obj.get(); } /** * 获取单例对象 如果定义了name对应的provider则使用它构造对象并返回 *

* 如果provider未定义,返回空 * * @param name * @return */ public Object get(K name) { return this.get(name, null, null); } public void clearObjects() { this.objects.forEach((k, v) -> v.clear()); } public void clear() { this.objects.clear(); } /** * 单例模式对象工厂 (实现了序列化机制) */ public static class SerialFactory extends SObjectFactory implements Serializable { /** * 获取实例 * * @return */ public static

SerialFactory inst() { return new SerialFactory<>(); } public SerialFactory() { super(); } private SerialFactory(Map> objects) { super(objects); } private Object readResolve() { return new SerialFactory<>(this.objects); } } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy