JAVA自定义缓存设计方案

时间:2022-02-02 18:07:44

缓存有一个缓存基类,其它缓存类都继承基类.去实现一些方法,其它缓存类可以在里面写自己特有的方法.以带到不同的需求.实现基类主要是方便管理缓存.

基类内容如下:

import java.util.ArrayList;

import java.util.HashMap;

import java.util.List;

public abstractclass BaseCache<T> {

/*

* Map将作为缓存的最大集合它保存了所有子类对象中的数据(特殊的除外)子类数据将以map集合存放

*/

static HashMap<String, HashMap<String,?>> _map = new HashMap<String, HashMap<String,?>>();

/**

* 集合主要用于当我们在外部调用执行把_map清空之后需要重新加载所有初始化的数据的时候,用到此集合.

* 此集合保存了所有继承此基类的对象!所以在基类继承的时候需要把基类对象保存在此集合

* (当然如果有一个方法可以返回一个基类的所有子类就好了!)

*/

static List<BaseCache>_list = new ArrayList<BaseCache>();

protected void add(String key,HashMap<String,T> value){

_map.put(key, value);

}

protected void removre(String key){

_map.remove(key);

}

protected HashMap<String,T> getKey(String key){

return (HashMap<String,T>)_map.get(key);

}

protected static boolean containsKey(String key) {

return _map.containsKey(key);

}

/**

* 此方法是通过Map集合中的一个key去获取集合对象避免了去通过子类实例化之后去调用getObject()的瓶颈

*

* 注:调用此方法之前请确保数据已经加载结束否则抛出NullPointerException异常

*/

public List<T> getList(String key){

if (containsKey(key)) {

HashMap<String,T> l_map = getKey(key);

List<T> l_list = new ArrayList<T>();

for(T o:l_map.values())

l_list.add(o);

return l_list;

}else{

throw newNullPointerException();

}

}

/**

* 当外层使用此方法的时候将调用子类的方法

* 子类将先调用父类的getKey()方法查询是否存在此key,存在就直接返回

* 不存在就调用子类自己的数据加载方法

* @paramkey

* @return

*/

public abstract HashMap<String, T> getObject();

/**

* 用于刷新当前缓存已达到数据同步

*/

public abstractvoid refresh();

/**

* 执行所有初始化数据加载

*/

public finalstatic void loadAllData(){

for(BaseCache cache:_list)

cache.refresh();

}

}

再给一个实现类的例子:

import java.util.HashMap;

import com.xx.Atype;

public finalclass IAtypeCacheBean extends BaseCache<Atype> {

public staticfinal String KEY ="atype";

static IAtypeCacheBean typeCache = new IAtypeCacheBean();

private IAtypeCacheBean() {

_list.add(typeCache);//添加基类对象

}

public staticfinal synchronized IAtypeCacheBean getInit(){

if(typeCache==null)

typeCache = new IAtypeCacheBean();

typeCache.getObject();

return typeCache;

}

private final synchronizedvoid addChannelCache() {

add(KEY, this.getlistP());

}

@Override

public HashMap<String, Atype> getObject() {

// TODO Auto-generated method stub

if (!containsKey(KEY)) {

addChannelCache();

}

HashMap<String, Atype> map = getKey(KEY);

return map;

}

@Override

public void refresh() {

// TODO Auto-generated method stub

addChannelCache();

}

private HashMap<String, Atype> getlistP(){

//这里获取数据处理返回

return null ;

}

//----------子类可以扩展自己的方法以达到不同需求

}

通过以上两个类,我相信你也会用了,下一部是数据加载类些好了,方法也有了,当然是项目启动的时候把数据加载到堆中去啊.

我想很多人应该是知道怎么写的, sservlet是可以在web.xml中进行配置成为加载类的.

import com.xx.BaseCache;

public class ConFigServlet extends HttpServlet {

public void init() throws ServletException {

//项目初始化加载数据

BaseCache.loadAllData();

}

}

Web.xml文件配置如下:

<servlet>

<servlet-name>loadDBSourceServlet</servlet-name>

<servlet-class>

com.xx.ConFigServlet//这是那个servlet的路径

</servlet-class>

<load-on-startup>2</load-on-startup>//这句很重要至于里面的数字写多少自己百度吧.

</servlet>

到这里,这一整套的方案出来了.就是使用了.因为java一切皆为对象,所以我们在往数据库插入一条数据之后我们只需要做一件事就是获取对应保存在缓存中的map ,然后把插入数据库的数据对象放入这个map里面,这样就也不用重新查询数据就达到了数据的同步.(删除也一样的原理设计的时候用map的原因就是方便了)

到这里我就不说了提醒大家一下:在使用的时候一定要注意数据的同步.