若依系统分页工具学习-PageHelper篇十三

这是我参与11月更文挑战的第24天,活动详情查看:2021最后一次更文挑战

在昨天的文章中,我们介绍了PageHelper中的cache包以及简单介绍了包中各个类的属性与方法;还介绍了Java中一种加载类的方式:Class.forName,并且通过查看com.mysql.jdbc.Driver代码,我们知道,可以通过这种方式可以执行类中的静态代码段。

昨天的问题

我们先来看一下昨天最后留的问题:

com.google.common.cache.Cache是什么样的呢?

我们先来看一下com.google.common.cache.Cache的源代码:

1
2
3
4
5
java复制代码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中的那句代码:

1
java复制代码Class.forName("com.google.common.cache.Cache");

就成了单纯检测执行环境中是否能够加载com.google.common.cache.Cache类。

CacheFactory指定类名的方式

我们来看看CacheFactorycreateCache是如何通过参数sqlCacheClass指定类名生成指定对象的。

当指定sqlCacheClass时,将执行以下代码:

1
2
3
4
5
6
7
8
9
10
11
java复制代码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的解析很好理解,生成指定的类。

第二行:

1
java复制代码Constructor<? extends Cache> constructor = clazz.getConstructor(Properties.class, String.class);

从字面意思我们判断,首先是通过第一句获得指定类,然后通过getConstructor获取类的构造器。

第三行:

1
java复制代码return constructor.newInstance(properties, prefix);

通过构造器生成指定类的一个对象,并且通过上面构造器后面的<? Extends Cache>,我们知道,实现的缓存类需要是com.github.pagehelper.cache.Cache接口的一个实现。

当然,在PageHelper中就有两个实现GuavaCache以及SimpleCache

并且通过查看SimpleCache的代码,我们发现其中的构造器通过cacheBuilder一步一步的实现了成员变量CACHE的初始化,一步一步的判断是否设置了配置文件xxx.typeClass.evictionClassxxx..flushInterval.size等等。

GuavaCache同样也是使用cacheBuilder去逐步构造对象的。

这种构造数据的方式曾在《Effective Java》中提到过,非常便利,值得学习!

本文转载自: 掘金

开发者博客 – 和开发相关的 这里全都有

0%