我们介绍了PageHelper中的cache包以及简单介绍了包中各个类的属性与方法;还介绍了Java中一种加载类的方式:Class.forName
,并且通过查看com.mysql.jdbc.Driver
代码,我们知道,可以通过这种方式可以执行类中的静态代码段。
昨天的问题
我们先来看一下昨天最后留的问题:
com.google.common.cache.Cache
是什么样的呢?
我们先来看一下com.google.common.cache.Cache
的源代码:
package com.google.common.cache;
public abstract interface Cache<K,V> {
public abstract V getIfPresent(java.lang.Object arg0);
// 此处省略其他方法代码
}
我们发现 com.google.common.cache.Cache
实际上是一个接口,并且其中也并没有任务的静态static
代码段需要执行,其中的方法也都是抽象abstract
修饰的。
反过来我们再去看PageHelper中的那句代码:
Class.forName("com.google.common.cache.Cache");
就成了单纯检测执行环境中是否能够加载 com.google.common.cache.Cache
类。
CacheFactory指定类名的方式
我们来看看CacheFactory
中createCache
是如何通过参数sqlCacheClass
指定类名生成指定对象的。
当指定sqlCacheClass
时,将执行以下代码:
try {
Class<? extends Cache> clazz = (Class<? extends Cache>) Class.forName(sqlCacheClass);
try {
Constructor<? extends Cache> constructor = clazz.getConstructor(Properties.class, String.class);
return constructor.newInstance(properties, prefix);
} catch (Exception e) {
return clazz.newInstance();
}
} catch (Throwable t) {
throw new PageException("Created Sql Cache [" + sqlCacheClass + "] Error", t);
}
第一行: 结合我们之前对Class.forName
的解析很好理解,生成指定的类。
第二行:
Constructor<? extends Cache> constructor = clazz.getConstructor(Properties.class, String.class);
从字面意思我们判断,首先是通过第一句获得指定类,然后通过getConstructor
获取类的构造器。
第三行:
return constructor.newInstance(properties, prefix);
通过构造器生成指定类的一个对象,并且通过上面构造器后面的 <? Extends Cache>
,我们知道,实现的缓存类需要是 com.github.pagehelper.cache.Cache
接口的一个实现。
当然,在PageHelper中就有两个实现 GuavaCache
以及 SimpleCache
。
并且通过查看 SimpleCache
的代码,我们发现其中的构造器通过 cacheBuilder
一步一步的实现了成员变量CACHE
的初始化,一步一步的判断是否设置了配置文件xxx.typeClass
,.evictionClass
,xxx..flushInterval
,.size
等等。
而 GuavaCache
同样也是使用cacheBuilder去逐步构造对象的。
专栏:若依框架