技术开发 频道

剖析Jive的缓存机制


IT168技术文档】 
    图2中Forum表示论坛,Thread表示论坛贴子的线索,Message表示论坛贴子,它们的关系是:Forum包括数条Thread,Thread包括数条Message。

 由图2可见,DbForum类、DbForumThread类和DbForumMessage类的实例对象都包含一个 DbForumFactory类的实例对象factory。DbForum类、DbForumThread类和DbForumMessage类被DbForumFactory生产出来,同时它们也通过DbForumFactory来访问缓存。而在DbForumFactory中则包含一个DatabaseCacheManager类的实例对象cacheManager。它负责管理所有的缓存对象,这些缓存对象就是ForumCache类、ForumThreadCache类和ForumMessageCache类的实例。ForumCache类、 ForumThreadCache类和ForumMessageCache类继承自同一个抽象类DatabaseCache,而在DatabaseCache类中,有一个LongCache型的成员变量cache。这样中间层就和低层的数据结构结合起来了。

 现在以thread线索对象的获得为例,说明中间层是如何运作的。请看代码摘要:
DbForum.java public class DbForum implements Forum, Cacheable { ...... public ForumThread getThread(long threadID)throws   ForumThreadNotFoundException{ return factory.getThread(threadID, this); } ...... } DbForumFactory.java public class DbForumFactory extends ForumFactory { ...... protected DbForumThread getThread(long threadID, DbForum forum)throws     ForumThreadNotFoundException{ DbForumThread thread = cacheManager.threadCache.get(threadID); return thread; } ...... } ForumThreadCache.java public class ForumThreadCache extends DatabaseCache { ...... public DbForumThread get(long threadID)throws   ForumThreadNotFoundException{  //缓存中寻找以threadID为编号的DbForumThread对象 DbForumThread thread = (DbForumThread)cache.get(threadID); if (thread == null) {   //如果在缓存中找不到该对象 //新建一个以threadID为编号的DbForumThread对象 thread = new DbForumThread(threadID, factory); //将新建对象加入缓存 cache.add(threadID, thread); } return thread; } ...... } DbForumThread.java public class DbForumThread implements ForumThread, Cacheable { ...... protected DbForumThread(long id, DbForumFactory factory)throws     ForumThreadNotFoundException{ this.id = id; this.factory = factory; //读取数据库,其中id对应数据库中的jiveThreadProp表中的threadID字段 loadFromDb(); isReadyToSave = true; } ...... }
 从上面的代码可以看到,当调用DbForum类 的getThread(long threadID)方法获得一个编号为threadID的线索对象时,实际上调用的是DbForumFactory类中的getThread(long threadID, DbForum forum)方法,而GetThread方法则是调用ForumThreadCache类的get方法来完成任务的。ForumThreadCache类里get(long threadID)方法则根据threadID到缓存中找相应的线索对象,如果缓存中有该对象就直接得到,没有则新建一个DbForumThread对象,再把该对象放入缓存中。看到这里也许有人会奇怪,好像程序中根本没有连接数据库的语句。我们可以从DbForumThread类的代码中找到答案。原来Jive在新建一个DbForumThread对象时,就已经用loadFromDb()方法把数据读出来了。另一方面,如果在缓存中找到了DbForumThread对象,程序根本就不会新建DbForumThread对象,因而就好象没有数据库的操作,这实际上就是通过缓存机制所要达到的目的。

 Message帖子对象的获得与Thread对象的获得类似,因此就不再重复了。从上面介绍可以看出,只要得到论坛线索的编号threadID,就可以得到对应的线索对象,不管它是从缓存中来,还是从数据库中来。那么threadID是如何从Jsp页面传到中间层的呢?让我们来看上层访问接口的运行机制吧。

 上层访问接口

 上层访问接口的主要功能是连接JSP页面和中间层。换句话说,就是把JSP页面中要调用的Thread、Message对象的ID传递到中间层。下面给出访问Thread相关类的类图(访问Message机制图类似,故省略),见图3。其中的forum.jsp是显示论坛内容的页面。在这里,我们把forum.jsp看成是一个特殊的类,它里面有一个ForumThreadIterator类的实例变量threads和DbForum类的实例变量forum,故它和ForumThreadIterator类及DbForum类的关系应是关联关系。


 先来看forum.jsp和DbForum 类的部分代码:
0
相关文章