在如今缓存框架横行的时代,还是有必要了解下基本的缓存原理,本文讲解下纯java实现的缓存,可以用于一些小项目中做测试使用。在真实的项目中,一般很少使用不带框架的纯缓存。
####1.基本类,即需要缓存的对象

public class Account {
	private int id;
	private String name;
}

####2.缓存管理器
主要负责通用的对象添加/更新/删除、查询等操作

package com.test.spring.cacheCommon;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

/**
 * 定义一个缓存管理器,在一个工程中可以公用
 * 负责实现 对象添加/修改/删除
 * 值对象是泛型
 */
public class MyCacheManager<T> {
	
	private Map<Object, T> cache = new ConcurrentHashMap<>();
	
	//根据key获取对象值
	public T getValue(Object key)
	{
		return cache.get(key);
	}
	
	//添加/更新对象
	public void addOrUpdateCache(Object key,T value)
	{
		cache.put(key, value);
	}
	
	//根据key来删除缓存中一条记录
	public void evictCache(Object key)
	{
		if (cache.containsKey(key)) {
			cache.remove(key);
		}
	}
	
	//清空所有缓存记录
	public void evictCache(){
		cache.clear();
	}
}

####3.业务类

package com.test.spring.cacheCommon;

/**
 * 业务类 
 */
public class MyAccountService {
	
	private MyCacheManager<Account> myCacheManager;
	
	//构造器
	public MyAccountService() {
		
		myCacheManager = new MyCacheManager<>();
	}
	
	//根据key获取对象值
	public Account getAccountByName(String name){
		Account result = myCacheManager.getValue(name);
		if (result != null) {
			//该对象存在于缓存中,直接返回
			System.out.println("直接从缓存返回");
			return result;
		}
		
		//否则,去数据库中查询
		result = getFromDB(name);
		if (result != null) {
			//将数据库查询结果更新到缓存中去
			myCacheManager.addOrUpdateCache(name, result);
		}
		return result;
	}
	
	//清空所有缓存记录
	public void reload()
	{
		System.out.println("清空缓存");
		myCacheManager.evictCache();
	}
	
	//数据库查询
	private Account getFromDB(String name) {
		System.out.println("去数据库查询");
		return new Account(name);
	}
	
}

####4.测试类

public class Main {
	
	public static void main(String[] args) {
		
		MyAccountService myAccountService = new MyAccountService();
		
		//第一次查询,去数据库查询
		myAccountService.getAccountByName("张三");
		//第二次查询,从缓存中查询
		myAccountService.getAccountByName("张三");
		
		//清空缓存
		myAccountService.reload();
		//第三次查询,从数据库查询
		myAccountService.getAccountByName("张三");
		//第四次查询,从缓存中查询
		myAccountService.getAccountByName("张三");
	}

####5.输出结果

去数据库查询
直接从缓存返回
清空缓存
去数据库查询
直接从缓存返回

####总结
从输出结果来看,很明显达到了缓存的目的。但是也很明显发现诸多缺点:
1.缓存代码与业务代码耦合度太高。业务类(MyAccountService)中掺杂了太多的缓存逻辑,不利于修改。
2.随着业务的增加,缓存管理器中的代码会越来越多,不利于维护。
3.不灵活,缓存的存储写得比较死,不能快速的切换为三方缓存模块。
因此,需要改善,请看spring分类中springCache。