Ehcache 缓存
为方便理解,本章涉及示例代码已上传至 gitee
==>获取示例代码请点击这里。。。
拉取示例代码时,请拉取所有分支,master 分支只是做了示例的初始化
该节仅作了解,推荐使用 Redis 实现方式
在 MyBatis 的二级缓存中使用 Ehcache ,只需如下配置即可,使用默认配置,即基于虚拟机内存实现缓存存储:
// 在对应的 XML 文件中如下配置
// 将缓存的 type 设置为 Ehcache 实现类
<cache type="org.mybatis.caches.ehcache.EhcacheCache" />
// 注解方式配置
@CacheNamespace(implementation = org.mybatis.caches.ehcache.EhcacheCache.class)
便可以使用 Ehcache 了,在初始化 MyBatis 阶段,会将基本缓存实现类设置为 Ehcache,大概流程代码如下:
XMLMapperBuilder.class
private void cacheElement(XNode context) {
if (context != null) {
// 获取 XML 文件中 <cache> 标签的 type 属性;如果未设置 则默认为 PERPETUAL;这里我们设置了使用 Ehcache ,即
// type = "org.mybatis.caches.ehcache.EhcacheCache"
String type = context.getStringAttribute("type", "PERPETUAL");
// 加载 EhcacheCache 的 Class 对象
Class<? extends Cache> typeClass = typeAliasRegistry.resolveAlias(type);
String eviction = context.getStringAttribute("eviction", "LRU");
Class<? extends Cache> evictionClass = typeAliasRegistry.resolveAlias(eviction);
Long flushInterval = context.getLongAttribute("flushInterval");
Integer size = context.getIntAttribute("size");
boolean readWrite = !context.getBooleanAttribute("readOnly", false);
boolean blocking = context.getBooleanAttribute("blocking", false);
Properties props = context.getChildrenAsProperties();
// 传入 typeClass ,设置为基本缓存实例
builderAssistant.useNewCache(typeClass, evictionClass, flushInterval, size, readWrite, blocking, props);
}
}
在上面这段代码中,拿到我们在接口对应 XML 文件中设置的 cache 标签的 type 值,通过反射来加载 EhcacheCache 的 Class 对象,具体的方法就是:
Class<?> c = Class.forName(name, true, cl);
下面我们来看 EhcacheCache 的构造器方法:
public class EhcacheCache extends AbstractEhcacheCache {
public EhcacheCache(String id) {
super(id);
// 关键的部分在这里;CACHE_MANAGER 的创建在其父类中,下一个代码块
if (!CACHE_MANAGER.cacheExists(id)) {
CACHE_MANAGER.addCache(id);
}
this.cache = CACHE_MANAGER.getEhcache(id);
}
}
public abstract class AbstractEhcacheCache implements Cache {
// 静态属性,只会被初始化一次
protected static CacheManager CACHE_MANAGER = CacheManager.create();
...
}
由于 CACHE_MANAGER 为静态属性,所以,在第一次创建 EhcacheCache 的 Class 对象时;会被初始化,之后,再次创建 sqlSessionFactory ,再次创建 EhcacheCache 的 Class 对象时,由于 CACHE_MANAGER 的静态属性,不会被再被初始化,而缓存对象便存储在其中。
补充:EhCache 还可以进行缓存数据的持久化与分布式缓存,有兴趣可自行查找,这里不做介绍。