FreeMarker代码分析第七篇

2021SC@SDUSC

util包

IdentityHashMap.java

代码分析

package freemarker.ext.util;

import java.util.AbstractCollection;
import java.util.AbstractMap;
import java.util.AbstractSet;
import java.util.Collection;
import java.util.ConcurrentModificationException;
import java.util.Iterator;
import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Set;

/**
 * Was used instead of {@link java.util.IdentityHashMap} before that was added to Java itself in Java 1.4. 
 * 
 * @deprecated Use {@link java.util.IdentityHashMap} instead.
 */
@SuppressWarnings("rawtypes")
@Deprecated
public class IdentityHashMap
    extends AbstractMap
    implements Map, Cloneable, java.io.Serializable {

    public static final long serialVersionUID = 362498820763181265L;
    /**
     * 存储哈希表数据
     */
    private transient Entry table[];

    /**
     * 用于保存哈希表中mapping的数量
     */
    private transient int count;

ModelCache.java

代码分析

package freemarker.ext.util;

import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.util.IdentityHashMap;
import java.util.Map;

import freemarker.template.TemplateModel;
import freemarker.template.TemplateModelAdapter;

/**
 * 此类被各种包装用来用于实现模型的内部缓存
 */
public abstract class ModelCache {
    private boolean useCache = false;
    private Map<Object, ModelReference> modelCache = null;
    private ReferenceQueue<TemplateModel> refQueue = null;
    
    protected ModelCache() {
    }
    
    /**
     * Sets whether this wrapper caches model instances. Default is false.
     * When set to true, calling {@link #getInstance(Object)} 
     * multiple times for the same object will return the same model.
     */
    public synchronized void setUseCache(boolean useCache) {
        this.useCache = useCache;
        if (useCache) {
            modelCache = new IdentityHashMap<>();
            refQueue = new ReferenceQueue<>();
        } else {
            modelCache = null;
            refQueue = null;
        }
    }

    /**
     * @since 2.3.21
     */
    public synchronized boolean getUseCache() {
        return useCache;
    }
    
    public TemplateModel getInstance(Object object) {
        if (object instanceof TemplateModel) {
            return (TemplateModel) object;
        }
        if (object instanceof TemplateModelAdapter) {
            return ((TemplateModelAdapter) object).getTemplateModel();
        }
        if (useCache && isCacheable(object)) {
            TemplateModel model = lookup(object);
            if (model == null) {
                model = create(object);
                register(model, object);
            }
            return model;
        } else {
            return create(object);
        }
    }
    
    protected abstract TemplateModel create(Object object);
    protected abstract boolean isCacheable(Object object);
    
    public void clearCache() {
        if (modelCache != null) {
            synchronized (modelCache) {
                modelCache.clear();
            }
        }
    }

    private final TemplateModel lookup(Object object) {
        ModelReference ref = null;
        // NOTE: we're doing minimal synchronizations -- which can lead to
        // duplicate wrapper creation. However, this has no harmful side-effects and
        // is a lesser performance hit.
        synchronized (modelCache) {
            ref = modelCache.get(object);
        }

        if (ref != null)
            return ref.getModel();

        return null;
    }

    private final void register(TemplateModel model, Object object) {
        synchronized (modelCache) {
            // Remove cleared references
            for (; ; ) {
                ModelReference queuedRef = (ModelReference) refQueue.poll();
                if (queuedRef == null) {
                    break;
                }
                modelCache.remove(queuedRef.object);
            }
            // Register new reference
            modelCache.put(object, new ModelReference(model, object, refQueue));
        }
    }

    /*
    在模型缓存中注册的特殊软参考。
    当它被清除 (即模型变得遥不可及) 时, 
    它会从模型缓存中删除自己
     */
    private static final class ModelReference extends SoftReference<TemplateModel> {
        Object object;

        ModelReference(TemplateModel ref, Object object, ReferenceQueue<TemplateModel> refQueue) {
            super(ref, refQueue);
            this.object = object;
        }

        TemplateModel getModel() {
            return this.get();
        }
    }

}

ModelFactory.java

代码分析

package freemarker.ext.util;

import freemarker.template.ObjectWrapper;
import freemarker.template.TemplateModel;

/*
用于创建在 {@link ModelCache}中的不同包装模型的接口
 */
public interface ModelFactory {
    /*
    为属于特殊包装的对象创建包装模型
     */
    TemplateModel create(Object object, ObjectWrapper wrapper);
}

WrapperTemplateModel.java

代码分析

package freemarker.ext.util;

import freemarker.template.TemplateModel;

/*
模板模型的通用界面,用于包装一些底层对象,
并希望提供对该包裹对象的访问权限。
 */
public interface WrapperTemplateModel extends TemplateModel {
    /*
    检索此模型包裹的原始对象。
     */
    public Object getWrappedObject();
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值