参照别人写的一个完全自定义的缓存实现,即不用任何第三方的组件来实现某种对象的内存缓存。
场景是:对一个用户查询方法做缓存,以用户id为 key,用户本身为 value,当以相同的id查询用户的时候,直接从缓存中返回结果,否则更新缓存。用户查询服务还支持 reload 缓存(即清空缓存)。
首先定义一个实体类:用户类(User),具备基本的 id,name ,password属性,且具备 getter 和 setter 方法
清单 1. User.java
package cache;
import java.io.Serializable;
public class User implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer id;
private String name;
private String password;
public User() {
}
public User(int id, String name, String password) {
this.id = id;
this.name = name;
this.password = password;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public String getPassword() {
return password;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
public void setPassword(String password) {
this.password = password;
}
}
然后定义一个缓存管理器,这个管理器负责实现缓存逻辑,支持对象的增加、修改和删除,支持值对象的泛型。如下:
清单 2. MyCacheManager.java
package cache;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
public class MyCacheManager {
private Map cache = new ConcurrentHashMap();
// 获取缓存中的记录
public T getValue(Object key) {
return cache.get(key);
}
// 根据key更新缓存中的记录
public void addOrUpdateCache(String key, T value) {
cache.put(key, value);
}
// 根据 key 来删除缓存中的一条记录
public void evictCache(String key) {
if (cache.containsKey(key)) {
cache.remove(key);
}
}
// 清空缓存中的所有记录
public void evictCache() {
cache.clear();
}
}
现在我们有了实体类和一个缓存管理器,还需要一个提供用户查询的服务类,此服务类使用缓存管理器来支持用户查询缓存(如果需要从数据库中获取数据的话,请自己增加DAO层,并将一下构造体中的数据删除),如下:
清单 3. UserService.java
package cache;
import java.util.HashMap;
import java.util.Map;
public class UserService {
private MyCacheManager cache;
private static Map users = new HashMap();
public UserService() {
cache = new MyCacheManager();
users.put("41", new User(41, "fan01", "123"));
users.put("42", new User(42, "fan02", "123"));
users.put("43", new User(43, "fan03", "123"));
}
// 根据id,获取用户信息
public User getUserById(Integer id) {
User userCache = cache.getValue(id.toString());
if(null != userCache){
System.out.println("+++++++++++++++++++++++++++++++++++++++cache!!!");
return userCache;
}
User result = users.get(id.toString());
if(null != result){
cache.addOrUpdateCache(id.toString(), result);
System.out.println("+++++++++++++++++++++++++++++++++++++++数据库!!!");
}
return result;
}
// 根据id,清除缓存中的信息
public void evictCache(Integer key){
cache.evictCache(key.toString());
}
// 清除缓存中的信息
public void evictCache(){
cache.evictCache();
}
}
好的,一切OK,终于到测试环节了,写个测试类,如下:
清单 4. TestUserCache.java
package cache;
public class TestUserCache {
static UserService userService = new UserService();
public static void main(String[] args) {
// 开始查询账号
// 第一次查询,应该是数据库查询
userService.getUserById(41);
// 第二次查询,应该直接从缓存返回
userService.getUserById(41);
// 清除缓存中的用户信息
userService.evictCache();
System.out.println("清除缓存后,再次查询用户信息..........");
// 第一次查询,应该是数据库查询
userService.getUserById(41);
// 第二次查询,应该直接从缓存返回
userService.getUserById(41);
}
}
最后附上一张图片: