- 浏览: 498035 次
- 性别:
- 来自: 北京
文章分类
- 全部博客 (250)
- concurrent (11)
- io (1)
- CI (10)
- linux (57)
- windows (2)
- java (38)
- mac (4)
- eclipse (9)
- db (13)
- python (5)
- groovy (5)
- flex (7)
- hibernate (5)
- odb (8)
- netbeans (1)
- web (31)
- book (14)
- erlang (2)
- communication (2)
- virtualization (5)
- jUnit (0)
- jsf (1)
- perl (1)
- java jax-rs (5)
- Jenkins (2)
- Jenkins Plugin (3)
- android (2)
- git (1)
- big data (0)
- 试读 (1)
最新评论
-
yzzy4793:
讲的很清楚,明白
同步synchronized方法和代码块 -
aa51513:
中文乱码式硬伤
Jersey2.x对REST请求处理流程的分析 -
feiwomoshu1991:
...
同步synchronized方法和代码块 -
marshan:
启动失败的原因是加载的类版本冲突,因此你首先要保证依赖的版本和 ...
richfaces中facelet版本升级到2时的典型错误和解决办法 -
zhaohang6688:
请问我按照你的方式修改还是报错 错误信息还是这个 是为什么啊 ...
richfaces中facelet版本升级到2时的典型错误和解决办法
2005-10-11 16:03:27
今天在天乙社区(http://bbscs.laoer.com)发表了关于这个社区开元项目bbscs6.0流程分析的文章。由于这个项目始终没有像样的文档,我决定为初学者提供些帮助,同时也想得到高人指点。这篇文章也是我近一个月来的学习总结,原文如下:
天乙社区使用了当下几种流行的j2ee技术,设计较为合理,我最近一边学习相关技术,一边研究,大概有了一个初步认识。
在此,与各位天乙fans共享,如有错误,恳请各位指正。
我们从一个实际的流程入手来分析。就拿社区首页这个链接说起吧。
在left.jsp中,社区首页的链接是这样的
<html:link action="/in" target="bbscs_mainFrame"><img src="images/line_01_2_copy.gif" align="absmiddle" border="0"><img src="images/i_option_copy.gif" align="absmiddle" border="0"><bean:message key="left.ToMainText"/></html:link>
这句话有两个关键点:
1、<bean:message key="left.ToMainText"/>
2、action="/in"
1是struts的view部分特性。
2是struts的controll部分。
我们分别来说,先来看看view。
<bean:message>用于输出Resource Bundle中的一条消息,配置在<message-resources>的key中。我们在Struts-config.xml中找到
<message-resources parameter="ApplicationResources" />
对应的ApplicationResources.properties.GBK文件中,我找到了“left.ToMainText=社区首页”这句。
接下来我们看看流程是怎么往下走的,就是controll部分。
在Struts-config.xml中,我们找到action="/in"对应的mapping是这么写的:
<action input="/error.jsp" path="/in" scope="request" type="com.laoer.bbscs.web.action.In">
<forward name="in" path="/in.jsp" />
</action>
com.laoer.bbscs.web.action.In是我们想要的action。
我们来看看这个文件
public class In extends BaseAction {
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm,
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
……
UserInfo ui = getUserCache().getUserInfoFromCache(uc.getId());
if (ui == null) {
errors.add("error.getusererror", new ActionError("error.getusererror"));
saveErrors(httpServletRequest, errors);
return actionMapping.findForward("error");
}
ui = getUserInfoService().doExp(ui);
……
return actionMapping.findForward("in");
}
}
经过一番处理之后,返回到"in"。它对应的页面是/in.jsp。
这样,struts就帮我们完成了一次旅程,我们从一个链接入手,得到了一个页面。这就是VC部分。
刚才说,在action里做了一些处理,那么究竟是如何处理的呢,我们得到的页面有可能需要某些动态数据,那么这些数据又从哪里来呢
这就是spring和hibernate的事情了,就是MVC的M部分。
举两个例子。还是这个in.java文件。
getUserCache()哪来的?它来自com.laoer.bbscs.web.action.TopBaseAction。
我们来看看这个幕后的类TopBaseAction
public class TopBaseAction
extends Action {
public TopBaseAction() {
super();
}
protected SysInfo getSysInfo() {
return SysInfo.getInstance();
}
protected Forbid getForbid() {
return Forbid.getInstance();
}
protected IUserInfoService getUserInfoService() {
return (IUserInfoService) AppContext.getInstance().getAppContext().getBean("userInfoService");
}
……
protected UserInfoCache getUserCache() {
return (UserInfoCache) AppContext.getInstance().getAppContext().getBean("userInfoCache");
}
……
}
}
原来getUserCache()要从spring的配置文件applicationContext.xml中去寻找"userInfoCache"这个Bean。那么这个Bean到底是什么呢?
在applicationContext.xml中,我找到了这句:
<bean id="userInfoCache" class="com.laoer.bbscs.sys.UserInfoCache">
<property name="userInfoService">
<ref local="userInfoService"/>
</property>
</bean>
好了,我们放下一切,去com.laoer.bbscs.sys.UserInfoCache里看看究竟。这里有我们想要的函数getUserInfoFromCache:
public UserInfo getUserInfoFromCache(long id) {
UserInfo ui = (UserInfo) CacheManager.getCache(1).get(String.valueOf(
id));
if (ui == null) {
ui = this.getUserInfoService().findUserInfoById(new Long(id));
CacheManager.getCache(1).add(String.valueOf(id), ui);
}
return ui;
}
CacheManager位于com.laoer.bbscs.sys,使缓存管理类。
这个类用到了CacheFactory,如下:
public class CacheManager {
……
static {
managers = new CacheManager[4];
for (int i = 0; i < managers.length; i++) {
managers[i] = new CacheManager();
}
}
public CacheManager() {
this.cache = CacheFactory.getInstance();
}
}
这个工厂又是怎么初始化的呢?
public class CacheFactory {
……
public synchronized static ICache getInstance() {
try {
return (ICache) Class.forName("com.laoer.bbscs.sys.SysOSCache").newInstance();
}
……
}
接着看这个SysOSCache类:
public SysOSCache() {
admin = new GeneralCacheAdministrator();
}
终于找到缓存机制的根源了,GeneralCacheAdministrator()是oscache-2.0.2.jar这个缓存工具中的函数。
追溯到了底,我们往回返。在in.java中:
UserInfo ui = getUserCache().getUserInfoFromCache(uc.getId());这句就是通过spring的控制反转,找到缓存处理的类,然后从缓存中提取用户信息。
这个例子强调了spring的作用,我们在举个例子,看看spring是怎么讲流程往后走,直到数据库的。
ui = getUserInfoService().doExp(ui);
相同的经验
getUserInfoService()-[TopBaseAction.java]->"userInfoService"-[applicationContext.xml]->"com.laoer.bbscs.business.service.UserInfoSeviceImp"
好,我们来看看UserInfoSeviceImp.java这个类
public class UserInfoSeviceImp
implements IUserInfoService {
……
public UserInfo doExp(UserInfo userinfo) {
userinfo.setExp( (int) ( (userinfo.getLoginTimes() / 4) +
userinfo.getArticleNum() +
(userinfo.getStayTime() / 3600000) +
userinfo.getExpression()));
return this.getUserInfoDAO().saveUserInfo(userinfo);
}
……
}
doExp这个函数是计算经验值的,计算完毕set到userinfo中,并将它入库。
入库就是getUserInfoDAO().saveUserInfo(userinfo);这么简单的一句。我们去看看它背后的信息。
public IUserInfoDAO getUserInfoDAO() {
return this.userInfoDAO;
}
在applicationContext.xml中:
<bean id="userInfoDAO" class="com.laoer.bbscs.dao.hibernate.UserInfoHibernateDAO">
<property name="sessionFactory">
<ref local="mySessionFactory"/>
</property>
</bean>
UserInfoHibernateDAO类中,找我们需要的函数saveUserInfo()
public UserInfo saveUserInfo(UserInfo userinfo) {
try {
getHibernateTemplate().saveOrUpdate(userinfo);
return userinfo;
}
catch (DataAccessException ex) {
return null;
}
}
getHibernateTemplate()是spring.jar工具中org.springframework.orm.hibernate.support.HibernateDaoSupport中的函数,
返回值是HibernateTemplate类型。用来简化我们处理数据库事务中的工作。
我们的数据库处理流程分析到此结束,回到in.java中,我么也就知道ui = getUserInfoService().doExp(ui);的意义了。
以上就是spring的功能。最后再简单说说hibernate。
getHibernateTemplate().saveOrUpdate(userinfo);之后,我们就再不用些什么了,全交给hibernate处理。
那么它又是如何工作的呢?
在applicationContext.xml中,我们找到:
<bean id="mySessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/laoer/bbscs/bean/UserInfo.hbm.xml</value>
……
我们还看看UserInfo.hbm.xml这个文件:
<class name="com.laoer.bbscs.bean.UserInfo" table="BBSCS_USERINFO">这是对应的类和对应的表的定义。
以下是对应的表的结构:
<param name="table">BBSCS_TABLEID</param>
<param name="column">IDValue</param>
<param name="id">1</param>
<param name="increment">15</param>
</generator>
</id>
<property column="UserName" length="20" name="username" not-null="true" type="string"/>
<property column="NickName" length="60" name="nickname" not-null="true" type="string"/>
……
到此,完成了流程的简单分析。
由于还处于学习中,水平有限,以上文字仅供参考,如有谬误,还望海涵,并希望你能寓于指点。
在此,与各位天乙fans共享,如有错误,恳请各位指正。
我们从一个实际的流程入手来分析。就拿社区首页这个链接说起吧。
在left.jsp中,社区首页的链接是这样的
<html:link action="/in" target="bbscs_mainFrame"><img src="images/line_01_2_copy.gif" align="absmiddle" border="0"><img src="images/i_option_copy.gif" align="absmiddle" border="0"><bean:message key="left.ToMainText"/></html:link>
这句话有两个关键点:
1、<bean:message key="left.ToMainText"/>
2、action="/in"
1是struts的view部分特性。
2是struts的controll部分。
我们分别来说,先来看看view。
<bean:message>用于输出Resource Bundle中的一条消息,配置在<message-resources>的key中。我们在Struts-config.xml中找到
<message-resources parameter="ApplicationResources" />
对应的ApplicationResources.properties.GBK文件中,我找到了“left.ToMainText=社区首页”这句。
接下来我们看看流程是怎么往下走的,就是controll部分。
在Struts-config.xml中,我们找到action="/in"对应的mapping是这么写的:
<action input="/error.jsp" path="/in" scope="request" type="com.laoer.bbscs.web.action.In">
<forward name="in" path="/in.jsp" />
</action>
com.laoer.bbscs.web.action.In是我们想要的action。
我们来看看这个文件
public class In extends BaseAction {
public ActionForward execute(ActionMapping actionMapping,
ActionForm actionForm,
HttpServletRequest httpServletRequest,
HttpServletResponse httpServletResponse) {
……
UserInfo ui = getUserCache().getUserInfoFromCache(uc.getId());
if (ui == null) {
errors.add("error.getusererror", new ActionError("error.getusererror"));
saveErrors(httpServletRequest, errors);
return actionMapping.findForward("error");
}
ui = getUserInfoService().doExp(ui);
……
return actionMapping.findForward("in");
}
}
经过一番处理之后,返回到"in"。它对应的页面是/in.jsp。
这样,struts就帮我们完成了一次旅程,我们从一个链接入手,得到了一个页面。这就是VC部分。
刚才说,在action里做了一些处理,那么究竟是如何处理的呢,我们得到的页面有可能需要某些动态数据,那么这些数据又从哪里来呢
这就是spring和hibernate的事情了,就是MVC的M部分。
举两个例子。还是这个in.java文件。
getUserCache()哪来的?它来自com.laoer.bbscs.web.action.TopBaseAction。
我们来看看这个幕后的类TopBaseAction
public class TopBaseAction
extends Action {
public TopBaseAction() {
super();
}
protected SysInfo getSysInfo() {
return SysInfo.getInstance();
}
protected Forbid getForbid() {
return Forbid.getInstance();
}
protected IUserInfoService getUserInfoService() {
return (IUserInfoService) AppContext.getInstance().getAppContext().getBean("userInfoService");
}
……
protected UserInfoCache getUserCache() {
return (UserInfoCache) AppContext.getInstance().getAppContext().getBean("userInfoCache");
}
……
}
}
原来getUserCache()要从spring的配置文件applicationContext.xml中去寻找"userInfoCache"这个Bean。那么这个Bean到底是什么呢?
在applicationContext.xml中,我找到了这句:
<bean id="userInfoCache" class="com.laoer.bbscs.sys.UserInfoCache">
<property name="userInfoService">
<ref local="userInfoService"/>
</property>
</bean>
好了,我们放下一切,去com.laoer.bbscs.sys.UserInfoCache里看看究竟。这里有我们想要的函数getUserInfoFromCache:
public UserInfo getUserInfoFromCache(long id) {
UserInfo ui = (UserInfo) CacheManager.getCache(1).get(String.valueOf(
id));
if (ui == null) {
ui = this.getUserInfoService().findUserInfoById(new Long(id));
CacheManager.getCache(1).add(String.valueOf(id), ui);
}
return ui;
}
CacheManager位于com.laoer.bbscs.sys,使缓存管理类。
这个类用到了CacheFactory,如下:
public class CacheManager {
……
static {
managers = new CacheManager[4];
for (int i = 0; i < managers.length; i++) {
managers[i] = new CacheManager();
}
}
public CacheManager() {
this.cache = CacheFactory.getInstance();
}
}
这个工厂又是怎么初始化的呢?
public class CacheFactory {
……
public synchronized static ICache getInstance() {
try {
return (ICache) Class.forName("com.laoer.bbscs.sys.SysOSCache").newInstance();
}
……
}
接着看这个SysOSCache类:
public SysOSCache() {
admin = new GeneralCacheAdministrator();
}
终于找到缓存机制的根源了,GeneralCacheAdministrator()是oscache-2.0.2.jar这个缓存工具中的函数。
追溯到了底,我们往回返。在in.java中:
UserInfo ui = getUserCache().getUserInfoFromCache(uc.getId());这句就是通过spring的控制反转,找到缓存处理的类,然后从缓存中提取用户信息。
这个例子强调了spring的作用,我们在举个例子,看看spring是怎么讲流程往后走,直到数据库的。
ui = getUserInfoService().doExp(ui);
相同的经验
getUserInfoService()-[TopBaseAction.java]->"userInfoService"-[applicationContext.xml]->"com.laoer.bbscs.business.service.UserInfoSeviceImp"
好,我们来看看UserInfoSeviceImp.java这个类
public class UserInfoSeviceImp
implements IUserInfoService {
……
public UserInfo doExp(UserInfo userinfo) {
userinfo.setExp( (int) ( (userinfo.getLoginTimes() / 4) +
userinfo.getArticleNum() +
(userinfo.getStayTime() / 3600000) +
userinfo.getExpression()));
return this.getUserInfoDAO().saveUserInfo(userinfo);
}
……
}
doExp这个函数是计算经验值的,计算完毕set到userinfo中,并将它入库。
入库就是getUserInfoDAO().saveUserInfo(userinfo);这么简单的一句。我们去看看它背后的信息。
public IUserInfoDAO getUserInfoDAO() {
return this.userInfoDAO;
}
在applicationContext.xml中:
<bean id="userInfoDAO" class="com.laoer.bbscs.dao.hibernate.UserInfoHibernateDAO">
<property name="sessionFactory">
<ref local="mySessionFactory"/>
</property>
</bean>
UserInfoHibernateDAO类中,找我们需要的函数saveUserInfo()
public UserInfo saveUserInfo(UserInfo userinfo) {
try {
getHibernateTemplate().saveOrUpdate(userinfo);
return userinfo;
}
catch (DataAccessException ex) {
return null;
}
}
getHibernateTemplate()是spring.jar工具中org.springframework.orm.hibernate.support.HibernateDaoSupport中的函数,
返回值是HibernateTemplate类型。用来简化我们处理数据库事务中的工作。
我们的数据库处理流程分析到此结束,回到in.java中,我么也就知道ui = getUserInfoService().doExp(ui);的意义了。
以上就是spring的功能。最后再简单说说hibernate。
getHibernateTemplate().saveOrUpdate(userinfo);之后,我们就再不用些什么了,全交给hibernate处理。
那么它又是如何工作的呢?
在applicationContext.xml中,我们找到:
<bean id="mySessionFactory" class="org.springframework.orm.hibernate.LocalSessionFactoryBean">
<property name="dataSource"><ref local="dataSource"/></property>
<property name="mappingResources">
<list>
<value>com/laoer/bbscs/bean/UserInfo.hbm.xml</value>
……
我们还看看UserInfo.hbm.xml这个文件:
<class name="com.laoer.bbscs.bean.UserInfo" table="BBSCS_USERINFO">这是对应的类和对应的表的定义。
以下是对应的表的结构:
<param name="table">BBSCS_TABLEID</param>
<param name="column">IDValue</param>
<param name="id">1</param>
<param name="increment">15</param>
</generator>
</id>
<property column="UserName" length="20" name="username" not-null="true" type="string"/>
<property column="NickName" length="60" name="nickname" not-null="true" type="string"/>
……
到此,完成了流程的简单分析。
由于还处于学习中,水平有限,以上文字仅供参考,如有谬误,还望海涵,并希望你能寓于指点。
发表评论
-
Apache benchmarking
2013-11-17 16:15 1207NAME ab - Apache HTTP ser ... -
dojo 动态创建下拉菜单和输入框
2013-02-04 18:35 5988<!DOCTYPE HTML PUBLIC " ... -
动态加载css和java script
2013-01-24 18:53 2687var portalLoader = { dojo : ... -
[web architect] nginx1.2.6+ tomcat7+memcached1.2.6
2012-12-25 17:40 1329Load Balancer (Nginx) ... -
[web architect] tomcat+nginx单机
2012-12-24 18:39 994location / { ... -
Tomcat管理配置
2011-04-10 00:49 1217<?xml version='1.0' encod ... -
当前浏览器对html5的支持[狠图]
2011-01-15 03:08 4506html5是web的未来,这部巨作尚未完成,现在闪现的还只是一 ... -
richfaces中facelet版本升级到2时的典型错误和解决办法
2010-08-31 10:23 60092010-8-31 9:48:35 com.sun.faces ... -
探讨JSF·RichFaces分页的一种策略
2010-03-22 17:06 2807richfaces提供的rich:dataTable和rich ... -
checkbox与dataTable的完美结合
2010-02-23 17:43 11265本文介绍了richface的一种使用情况:datatable和 ... -
richface 皮肤
2010-01-07 13:36 1505一、绪 richface默认提供 ... -
RichFaces第一例
2009-12-29 14:30 1668学习JSF和RichFaces一周了,总结以一个小例子为介,分 ... -
大小写问题
2008-10-14 16:11 1248背景: 系统包括单点登录模块,存在多个数据库,有mysql和o ... -
九张图
2004-12-02 13:52 1196这些天一直在做查询页面。昨天碰到了这个:美工提供的在页面上显示 ... -
翻页的处理
2004-12-28 10:11 10841 翻页时排序:为了实 ... -
上传file前,判断上传文件的扩展名
2004-12-28 10:20 1647首先我不太确定Js能否扑捉到file的value,于是作了一个 ... -
上传文件前判空
2004-12-28 10:24 1265上传文件时如果下拉列表框或file框为空,会报错。下面就解决这 ... -
根据radio值动态显示file
2005-03-01 17:51 1270<html><head><met ... -
jsp/servlet 乱码解决小方法
2005-03-13 15:13 1333import java.io.UnsupportedEncod ... -
关于unconditional
2005-03-18 23:18 933在active状态调用destroyApp(boolean u ...
相关推荐
【标题】"对天乙社区bbscs8实现的详细分析一(附文档下载)" 提供的是关于一个名为“天乙社区”的BBS系统——BBScs8的深入解析。这个系列的分析文档可能涵盖了该社区平台的架构设计、功能模块、代码结构以及可能涉及到...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
JCarder 是一个用来查找多线程应用程序中一些潜在的死锁,通过对 Java 字节码的动态分析来完成死锁分析。 Java的Flash解析、生成器 jActionScript jActionScript 是一个使用了 JavaSWF2 的 Flash 解析器和生成器。...
Calendar万年历 1个目标文件 EJB 模拟银行ATM流程及操作源代码 6个目标文件,EJB来模拟银行ATM机的流程及操作:获取系统属性,初始化JNDI,取得Home对象的引用,创建EJB对象,并将当前的计数器初始化,调用每一个...