Struts1.1源码中有很多闪光点,本文就简单介绍Action类中的一个闪光点.Action是 Struts1.1框架中最富有弹性的类.它的主要职责是 : 1. 访问业务层 2. 为表示层准备数据对象 3. 处理上两项中可能发生的错误 它有两个特点 : 1. 在一个 Struts1.1应用中 ,每一个 Action类都只有一个实例 . 2. 有条件的线程安全 .
本文的目的主要是说明Struts1.1应用中的"每一个Action类都只有一个实例"这个特点是如何实现的,以对以后的工作有所启示.对于上文中的第二个特点,由于对"线程安全"这个命题(或概念)还存在争议,所以本文不作讨论,关于对它的讨论请参照http://www.uml.org.cn/j2ee/j2ee110601.htm
我们知道,在Struts配置文件中配置了每一个Action类的全限定名.Struts中的请求处理器(org.apache.struts.action.RequestProcessor)类,首先取得HTTP请求中的PATH值,并根据该值来获取相应的Action类的全限定名,因为在配置文件中一个Action类唯一对应一个PATH值.
第二,根据Action类的全限定名,从一个java.util.HashMap中获取该Action类的实例对象.如果取得的实例对象非NULL,则返回该对象.
第三,如果上一步取得的实例对象为NULL,则根据Action类的全限定名从类装载系统中导入并实例化.
第四,把从上一步中获得的Action类实例根据类的全限定名缓存在java.util.HashMap中.
代码实现如下:
protected Action processActionCreate( HttpServletRequest request, HttpServletResponse response, ActionMapping mapping) throws IOException { //1.根据请求PATH获取类名 String className = mapping.getType(); Action instance = null; synchronized (actions) {//actions为java.util.HashMap的实例. //2.根据类名取得类的实例.actions为java.util.HashMap的实例. instance = (Action) actions.get(className); if (instance != null) { return (instance); } try { //3.根据Action类的全限定名从类装载系统中导入并实例化. instance = (Action) RequestUtils.applicationInstance(className); } catch (Exception e) { response.sendError( HttpServletResponse.SC_INTERNAL_SERVER_ERROR, getInternal().getMessage( "actionCreate", mapping.getPath())); return (null); } instance.setServlet(this.servlet); //4.缓存Action类实例. actions.put(className, instance); } return (instance); }
"一个Action类只有一个实例"的实现,简单地说就是,缓存每一个被实例化的Action类.
|