【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类 的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对象,因而就好象没有数据库的操作,这实际上就是通过缓存机制所要达到的目的。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;
}
......
}
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 类的部分代码: