TA的每日心情 | 开心 2021-3-12 23:18 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
大家看这篇文章的时候,可以先看一下源代码,源代码列表地址为:http://blog.csdn.net/chen1255/archive/2010/01/21/5221675.aspx ,然后运行一下这个demo,我想大家对这个框架就有一个大概的概念,最后在这篇文章的帮助下,就可以彻底了解其中的奥秘了。
这个版本的框架,是没有配置文件的,所有的配置项都在web.xml里面,其原理和struts基本是一样的。这个框架没有任何异常处理(除开基本的Servlet异常处理)和日志文件控制,这些功能会在后续版本中添加。
这个框架分4个部分,它们依次是control,listener,util,view
下面我讲解一下这个框架的基本结构:
通过ControllerFactory 生成一个Action实例
1.这框架的核心是controllerservlet,它处理了框架的核心任务,控制着内部线程的走向,同时它的引用在web.xml文件中有配置,
如:
<servlet>
<description>NetCloudy Core team 2008-2010</description>
<display-name>This is main controller of framework</display-name>
<servlet-name>ControllerServlet</servlet-name>
<servlet-class>com.netcloudy.framework.core.control.ControllerServlet</servlet-class>
</servlet>
这和普通的servlet请求完全一样,其实框架就是在这种方式上发展而来的,struts1是同如上方法,struts2使用的的filter,它们原理都是一样的。这个类会过滤所有提交到服务器上的请求,它会截取以****.do结尾的请求,这里框架是依据web.xml配置文件截取
如:
<servlet-mapping>
<servlet-name>ControllerServlet</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
其实我们也可以自己定义别的截取方式如****.dox,那么框架就将截取以.dox结尾的请求,但我们必须注意这一点<servlet>--><servlet-name>必须与 <servlet-mapping>--><servlet-name>的名字一样,因为下面的过滤,是调用上面的类。
ControllerServlet这个核心类继承了 BaseServlet,因为在我们的常用的提交请求中大多数情况下我们只用post和get两种方式,所以框架就只写了这两个方法,如果有其他上面情况,用户也可以自己添加。
在BaseServlet中有一个abstract方法doService,这个是核心方法,是让post和get来调用这个方法,这个方法在ControllerServlet被实现。
在该方法中:
ControllerImpl impl = ControllerFactory.findController(this.getServletContext(), request);
这段代码的作用是根据用户提交的请求,向servlet 池中添加请求的action字节码(向内存中添加自己码),然后创建一个对应的action请求实例,如demo中的例子,TestAction.do?method=login,系统就将加载TestAction.class,创建一个TestAction的实例对象提供给用户使用。
因为ControllerAction extends ControllerImpl ,所有用ControllerImpl 来接收创建的action实例。(关于怎么创建实例,下面将要讲到)
当我们创建了实例之后,那么我们就是要使用它,这个action实例就相当于一台电脑,我们有了电脑还不行,还有有电,有互联网才能正常的上网啊。回到系统,我们用户提交的信息就相当于这里的电,没有这些信息action就没有什么具体的作用。所以方法中就出现了这么一行:impl.dealRequest(request, response),大家看了上面一点话,就很容易理解这是什么意思了。这段代码就是接收客户发过来的信息,让它加载到对于的action实例当中让action处理。这里有一个接收参数的是对象,它是View的实例,对于现在的系统,其实这个View可以换成String等(只要能够传递参数就行),但由于我们需要面向对象和方便以后面向接口编程,所以这里用View对象,其实这里面很多代码,用户都可以根据自己的要求进行更改,所以这个系统的另外一个好处就是方便用户修改,这个不像strut,它这么多代码,不还改,呵呵,说远了。
最后dealModelAndView(view, request, response),这个方法就是负责最后的跳转了,对于这个版本的系统,我觉得这个方法就没有什么讲的了,因为功能实在是太简单了。
在我们了解完了系统的整个架构了,那么我们就来了解一下细节吧.
1.ControllerFactory.findController(this.getServletContext(), request),就是这个方法,我们进入这个方法内部,大家是否觉得有一个熟悉的身影啊,对,就是 Class.forName(classFullName.trim()).newInstance(),这个方法在我们使用数据库连接包的时候,是不是经常用到(如果你没有见过,那么只能说用的技术太高档了,把这些基本的东西都封装了)。这个就是我们常说的反射,这一段代码的作用就是这个方法的作用,创建一个action实例对象,classFullName就是有两个部分构成=包名+Action名,关于包名,我们在web.xml中已经配置了:
<!-- 注意:action后面的‘.’(点)一定不要忘了-->
<param-value>com.csdn.action.</param-value>
LoadListener类通过
String actionPath=context.getInitParameter(ACTION_PACKAGE);
加载了这一段参数,然后把它保存在ServletContextEvent然后提供给我们使用。
Action名大家一看就知道了,就简单的分析一下请求的URL就可以得到了。
2.接下来让我们看一下具体执行的Action实例。大家看ControllerImpl类,里面有两个方法,一个是处理的方法,它调用了一个abstract方法。大家可能要问了,不这么写可以吗?为什么要这么写。我先回答一下为什么要这么写,因为ControllerImpl是所有Action的父类,系统必须去调用这个处理方法,但是每个action实例它们又不一样,所以父类提供一个相同的abstract方法,让子类自己去实现,这样系统就不管具体的action实例了,系统只需要调用这个方法就可以了,dealRequest方法返回了结果就是对于action实例的结果了。第一个问题大家就只有自己想了。
3.最后我们来看一下ControllerAction吧。这个类里面的方法也很简单,同样使用了反射的原理,因为我们已经得到对应的Action实例了,现在我们要调用里面对应的方法,我们可以使用Method的invoke方法来调用具体实例里面的方法
我想现在大家应该比较了解这个框架了,它的基本原理和struts是一样的,只是这个系统没有什么配置文件,很适合很小的web系统开发,因为在我们发行了web系统,一般没有必要再去更改里面的逻辑,即使重构。那么我要问大家一个问题,这个系统的最大不足在哪里(优点就不问了,呵呵)。
不足:这个系统是请求时加载,意思是有人请求时,我才加载Action实例,大家如果对计算机了解熟一点的话,就知道,加载应用程序是最消耗资源和时间的。这个框架在低用户量访问的时候没有什么问题,可是如果有100万级的访问量的话,我想服务器早死了,大家可以改进一下这个框架。这个问题将在0.0.3版本这解决,谢谢大家的关注。
我的邮件是:manager@netcloudy.com 有什么需要的可以发邮件给我。
源码下载:http://www.zzsz.hnzz.net/kj/cwb/dir8/mvc_core.rar |
|