paulwong

#

Java容器类Collection、List、ArrayList、Vector及map、HashTable、HashMap区别

Collection是List和Set两个接口的基接口
List在Collection之上增加了"有序"
Set在Collection之上增加了"唯一"

而ArrayList是实现List的类...所以他是有序的.
它里边存放的元素在排列上存在一定的先后顺序

而且ArrayList是采用数组存放元素
另一种List LinkedList采用的则是链表。

Collection和Map接口之间的主要区别在于:Collection中存储了一组对象,而Map存储关键字/值对。
在Map对象中,每一个关键字最多有一个关联的值。
Map:不能包括两个相同的键,一个键最多能绑定一个值。null可以作为键,这样的键只有一个;可以有一个或多个键所对应的
值为null。当get()方法返回null值时,即可以表示Map中没有该键,也可以表示该键所对应的值为null。因此,在Map中不能由get()方法来判断Map中是否存在某个键,而应该用containsKey()方法来判断。
继承Map的类有:HashMap,HashTable
HashMap:Map的实现类,缺省情况下是非同步的,可以通过Map Collections.synchronizedMap(Map m)来达到线程同步
HashTable:Dictionary的子类,缺省是线程同步的。不允许关键字或值为null

当元素的顺序很重要时选用TreeMap,当元素不必以特定的顺序进行存储时,使用HashMap。Hashtable的使用不被推荐,因为HashMap提供了所有类似的功能,并且速度更快。当你需要在多线程环境下使用时,HashMap也可以转换为同步的。

为什么要使用集合类
当你事先不知道要存放数据的个数,或者你需要一种比数组下标存取机制更灵活的方法时,你就需要用到集合类。

理解集合类
集合类存放于java.util包中。
集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。
集合类型主要有3种:set(集)、list(列表)和map(映射)。

(1)集 (Set):口袋
集(set)是最简单的一种集合,它的对象不按特定方式排序,只是简单的把对象加入集合中,就像往口袋里放东西。
对集中成员的访问和操作是通过集中对象的引用进行的,所以集中不能有重复对象。
集也有多种变体,可以实现排序等功能,如TreeSet,它把对象添加到集中的操作将变为按照某种比较规则将其插入到有序的对象序列中。它实现的是SortedSet接口,也就是加入了对象比较的方法。通过对集中的对象迭代,我们可以得到一个升序的对象集合。

(2)列表 (List):列表
列表的主要特征是其对象以线性方式存储,没有特定顺序,只有一个开头和一个结尾,当然,它与根本没有顺序的集是不同的。
列表在数据结构中分别表现为:数组和向量、链表、堆栈、队列。
关于实现列表的集合类,是我们日常工作中经常用到的,将在后边的笔记详细介绍。

(3)映射 (Map):键值对
映射与集或列表有明显区别,映射中每个项都是成对的。映射中存储的每个对象都有一个相关的关键字(Key)对象,关键字决定了对象在映射中的存储位置,检索对象时必须提供相应的关键字,就像在字典中查单词一样。关键字应该是唯一的。
关键字本身并不能决定对象的存储位置,它需要对过一种散列(hashing)技术来处理,产生一个被称作散列码(hash code)的整数值,散列码通常用作一个偏置量,该偏置量是相对于分配给映射的内存区域起始位置的,由此确定关键字/对象对的存储位置。理想情况下,散列处理应该产生给定范围内均匀分布的值,而且每个关键字应得到不同的散列码。

集合类简介
java.util中共有13个类可用于管理集合对象,它们支持集、列表或映射等集合,以下是这些类的简单介绍

集:
HashSet: 使用HashMap的一个集的实现。虽然集定义成无序,但必须存在某种方法能相当高效地找到一个对象。使用一个HashMap对象实现集的存储和检索操作是在固定时间内实现的.
TreeSet: 在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap.
列表:
Vector: 实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象。Vector是唯一的同步容器类??当两个或多个线程同时访问时也是性能良好的。(同步的含义:即同时只能一个进程访问,其他等待)
Stack: 这个类从Vector派生而来,并且增加了方法实现栈??一种后进先出的存储结构。
LinkedList: 实现一个链表。由这个类定义的链表也可以像栈或队列一样被使用。
ArrayList: 实现一个数组,它的规模可变并且能像链表一样被访问。它提供的功能类似Vector类但不同步。
映射:
HashTable: 实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。
HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。
WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。
TreeMap: 实现这样一个映象,对象是按键升序排列的。

下图是集合类所实现的接口之间的关系:
Set和List都是由公共接口Collection扩展而来,所以它们都可以使用一个类型为Collection的变量来引用。这就意味着任何列表或集构成的集合都可以用这种方式引用,只有映射类除外(但也不是完全排除在外,因为可以从映射获得一个列表。)所以说,把一个列表或集传递给方法的标准途径是使用Collection类型的参数。

List接口
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
和下面要提到的Set不同,List允许有相同的元素。
除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。
ArrayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。ArrayList当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
和LinkedList一样,ArrayList也是非同步的(unsynchronized)。
Map接口
请注意,Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。
HashMap类
HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。
----------------------------------------------------------------------------
1.-------------------->
List是接口,List特性就是有序,会确保以一定的顺序保存元素.
ArrayList是它的实现类,是一个用数组实现的List.
Map是接口,Map特性就是根据一个对象查找对象.
HashMap是它的实现类,HashMap用hash表实现的Map,就是利用对象的hashcode(hashcode()是Object的方法)进行快速(Hash)散列查找.(关于散列查找,可以参看<<数据结构>>)
2.-------------------->
一般情况下,如果没有必要,推荐代码只同List,Map接口打交道.
比如:List list = new ArrayList();
这样做的原因是list就相当于是一个泛型的实现,如果想改变list的类型,只需要:
List list = new LinkedList();//LinkedList也是List的实现类,也是ArrayList的兄弟类
这样,就不需要修改其它代码,这就是接口编程的优雅之处.
另外的例子就是,在类的方法中,如下声明:
private void doMyAction(List list){}
这样这个方法能处理所有实现了List接口的类,一定程度上实现了泛型函数.
3.--------------------->
如果开发的时候觉得ArrayList,HashMap的性能不能满足你的需要,可以通过实现List,Map(或者Collection)来定制你的自定义类

posted @ 2012-03-20 21:40 paulwong 阅读(1439) | 评论 (0)编辑 收藏

业务系统与工作流系统

通常工作流系统是独立的一个系统,必须以业务系统和工作流系统的观点才能比较好的理解业务系统。工作流系统负责节点的流转,即状态的改变。

  1. 业务系统如果增加一个业务对象,须增加一堆的服务方法,工作流系统面向的是流程,增加流程无需增加代码,因此启动流程的第一步,就要业务系统告诉工作流系统要管理哪个流程,即流程ID,然后工作流系统就记录下此流程实例
  2. 工作流系统面向的是流程配置文件,即bpmn20.xml,用TASK表示业务系统中的步骤,如果这一节点为USER TASK,则表示工作流系统会等待业务系统的触发而改变状态,业务系统会向客户端展示页面,收集信息并验证通过后才让工作流系统改变流程实例的状态;如果是自动任务,则工作流系统会自行改变状态,流转到下一节点。
  3. 由于处理USER TASK时,需业务系统自行判断,因此新增业务对象(表单)时,需新增业务代码,有别于OA系统,新增表单时,不用新增代码。
  4. USER TASK中允许配有页面展示的链接,业务系统可以从这里取得链接而返回给客户端。静态网页处理时,只需向客户端传实体HTML文件,由客户端解释成文本内容,动态网页实际上由服务器端生成文本内容再发给客户端。

posted @ 2012-03-20 10:26 paulwong 阅读(448) | 评论 (0)编辑 收藏

基于注解的SpringMVC+freemarker环境搭建

  1. 首先用IDE建一个web工程。(这个就不详细介绍了)
  2. 引入响应的jar包
  3. web.xml
    <?xml version="1.0" ?>
    <web-app xmlns="http://java.sun.com/xml/ns/javaee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation
    ="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
        version
    ="3.0">
        
    <!--  Spring 服务层的配置文件 -->
        
    <context-param>
            
    <param-name>contextConfigLocation</param-name>
            
    <param-value>classpath:applicationContext.xml</param-value>
        
    </context-param>
        
        
    <!--  Spring 容器启动监听器 -->
        
    <listener>
            
    <listener-class>org.springframework.web.context.ContextLoaderListener
            
    </listener-class>
        
    </listener>

        
    <servlet>
            
    <servlet-name>springmvc</servlet-name>
            
    <servlet-class>org.springframework.web.servlet.DispatcherServlet
            
    </servlet-class>
            
    <load-on-startup>1</load-on-startup>
        
    </servlet>
        
    <!--为DispatcherServlet建立映射 -->
        
    <servlet-mapping>
            
    <servlet-name>springmvc</servlet-name>
            
    <url-pattern>/</url-pattern>
        
    </servlet-mapping>
    </web-app>

  4. SpringMVC另外一个重要的配置文件。
    DispatcherServlet会根绝web.xml中配置的<servlet-name>去找<servlet-name>-servlet.xml的文件来加载spring的一些配置信息。我这里就应该取名叫springmvc-servlet.xml
    <?xml version="1.0" encoding="UTF-8"?>
    <beans 
        
    xmlns="http://www.springframework.org/schema/beans" 
        xmlns:xsi
    ="http://www.w3.org/2001/XMLSchema-instance"
        xmlns:p
    ="http://www.springframework.org/schema/p" 
        xmlns:context
    ="http://www.springframework.org/schema/context"
        xsi:schemaLocation
    ="http://www.springframework.org/schema/beans 
        http://www.springframework.org/schema/beans/spring-beans-2.5.xsd
        http://www.springframework.org/schema/context 
        http://www.springframework.org/schema/context/spring-context-2.5.xsd"
    >
        
        
    <!--对web包中的所有类进行扫描,以完成Bean创建和自动依赖注入的功能 -->
        
    <context:component-scan base-package="com.liba.spring.mvc"/>
        
        
    <!-- 启动Spring MVC的注解功能,完成请求和注解POJO的映射   请求映射-->
        
    <bean class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />
        
            
    <!--以下三种视图配置根据需要任选一种即可 -->

        
    <!--  一般的视图配置 -->
        
    <!--<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver" 
            p:prefix="/WEB-INF/view/" p:suffix=".jsp"/>
    -->
        
        
    <!-- 针对freemarker的视图配置 -->
        
    <bean id="viewResolver"
            class
    ="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
            
    <property name="cache" value="true" />
            
    <property name="prefix" value="" />
            
    <property name="suffix" value=".ftl" />
            
    <property name="contentType" value="text/html;charset=UTF-8"></property>
            
    <property name="requestContextAttribute" value="request" />
            
    <property name="exposeSpringMacroHelpers" value="true" />
            
    <property name="exposeRequestAttributes" value="true" />
            
    <property name="exposeSessionAttributes" value="true" />
        
    </bean>
            
            
        
    <!-- View resolvers can also be configured with ResourceBundles or XML files. 
            If you need different view resolving based on Locale, you have to use the 
            resource bundle resolver. 
    -->
        
    <!-- 这个是针对返回视图还是json值的视图配置   来分别处理同步和异步请求 -->
        
    <!--<bean
                class="org.springframework.web.servlet.view.ContentNegotiatingViewResolver">
                <property name="mediaTypes">
                    <map>
                        <entry key="html" value="text/html" />
                        <entry key="json" value="application/json" />
                    </map>
                </property>
                <property name="favorParameter" value="true" />
                <property name="viewResolvers">
                    <list>
                        <bean class="org.springframework.web.servlet.view.BeanNameViewResolver" />
                        <bean id="viewResolver"
                            class="org.springframework.web.servlet.view.freemarker.FreeMarkerViewResolver">
                            <property name="cache" value="true" />
                            <property name="prefix" value="" />
                            <property name="suffix" value=".ftl" />
                            <property name="contentType" value="text/html;charset=UTF-8"></property>
                            <property name="requestContextAttribute" value="request" />
                            <property name="exposeSpringMacroHelpers" value="true" />
                            <property name="exposeRequestAttributes" value="true" />
                            <property name="exposeSessionAttributes" value="true" />
                        </bean>
                    </list>
                </property>
                <property name="defaultContentType" value="text/html" />
            </bean>
            
    -->
    </beans>

  5. 如果是使用freemarker最为视图模板需要再spring的配置文件applicationContext.xml中加入以下配置
    <bean id="freemarkerConfig"
            class
    ="org.springframework.web.servlet.view.freemarker.FreeMarkerConfigurer">
            
    <property name="templateLoaderPath" value="/WEB-INF/view/" />
            
    <property name="freemarkerSettings">
                
    <props>
                    
    <prop key="template_update_delay">0</prop>
                    
    <prop key="default_encoding">UTF-8</prop>
                    
    <prop key="number_format">0.##########</prop>
                    
    <prop key="datetime_format">yyyy-MM-dd HH:mm:ss</prop>
                    
    <prop key="classic_compatible">true</prop>
                    
    <prop key="template_exception_handler">ignore</prop>
                
    </props>
            
    </property>
        
    </bean>

  6. Controller建立
    import javax.servlet.http.HttpServletRequest;

    import org.springframework.stereotype.Controller;
    import org.springframework.web.bind.annotation.RequestMapping;
    import org.springframework.web.bind.annotation.RequestMethod;
    import org.springframework.web.servlet.ModelAndView;

    @Controller
    public class SpringMvcController {

        @RequestMapping(value
    ="/welcome",method={RequestMethod.GET}
        
    public ModelAndView getFirstPage(HttpServletRequest request) {
                    
    //welcom就是视图的名称(welcom.ftl)
            ModelAndView mv = new ModelAndView("welcom");
            mv.addObject(
    "name""My First Spring Mvc");
            
    return mv;
        }

    }
    在url上敲http://localhost:8080/welcome就会到WEB-INF/view/welcom.ftl页面渲染数据
  7. welcom.ftl页面
    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
    <html>
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
    <title>Insert title here</title>
    </head>
    <body>
    Hello ${name}
    </body>
    </html>

    页面出来的效果:

    Hello My First Spring Mvc








posted @ 2012-03-19 21:32 paulwong 阅读(25876) | 评论 (3)编辑 收藏

架构师的素质

架构师最基本的素质,总结出两点,1是技术知识广度,2是业务行业深度。


1 架构师是技术领导。
架构师必须要有技术,而且还是领导。架构师要带领自己团队完成自己的任务,完全凭借自己的能力做事情,完全是匹夫之勇,根本不提倡。

2 架构师理解软件流程。
架构师必须了解软件流程,否则无法驱动整个团队前进,如果一个架构师不熟悉开发流程,无法协调产品线相关人员进行高效工作,也无法指导团队成员完成自己的工作。所以来说架构师一般不是空降兵(除非是全新的部门),因为空降兵一般不会熟悉新公司的开发流程,即使是同一个行业的,各个公司的差别还是很大。所以说听说某某去某某公司做首席架构师或者首席科学家,一般是高风险的事情,即使他对这个行业很了解。

3 架构师必须熟悉业务领域。
如果一个架构师不熟悉自己的行业,做的架构就是纸上谈兵,熟悉业务领域的架构师,才能很好的理解需求,做出合适的方案。互联网和网络安全是完全不同的两个方向,即使你熟悉里面的各种具体技术,但是以互联网的架构来做网络安全产品,肯定是100%的失败。
我做PKI的时候,项目最初的使用.net,使用微软的crytoAPI,开发的很顺利。后来来了一位新的架构师,觉得.net不能跨平台,决定?用java,做出产品后,发现找不到arm cpu的jdk,使用平台有限。再次决定使用openssl做,最后这个项目以失败而告终。后来我想过arm cpu都是嵌入式设备用的,根本没有任何嵌入式设备提供CA服务。

4 架构师必须要有广度的知识。
架构师考虑的问题必须全面,必须了解的要广,具体的细节可以不关注,因为细节变化很快。很多具体技术人员出身的架构师,只关注于具体的细节,某些方面做的很好,整体的性能很差。
下面这个项目的成功可以理解为一个笑话。某公司的两个部门都做c程序的,A部门做的平台使用的x86和mips,B部门使用平台是x86和 arm,后来A部门的一个模块要给B部门用,最后发现根本不能运行。最后A部门发现arm平台使用big endian模式,这样A部门的20多名员工,检查代码中所有非零整数,经过数个月苦战,才修改完毕。其实解决方法很简单,因B部门的代码也是首先在 x86做的,做的时候他们考虑了cpu的endian模式。这并不能说B部门架构师很牛,从另一个方面说他的无知。因为板子有跳线,专门切换cpu的是 big endian还是little endian,这样两个部门都可以不修改程序。

5 架构师必须是写程序的高手。
架构师一般都是?发人员出身,一般都是团队的核心。优秀的架构师应该了解团队使用各种技术,有了这些知识,才能和开发人软进行有效沟通。
有一个项目架构使用xml做配置,因为病毒库很庞大,最后导致xml 达30多兆,服务端的java程序使用dom 进行过滤的时候,30兆xml加载很慢,频繁出现out of memory。这个项目后来搁浅。根据以前的经验发现 msxml加载30多M的xml 不过几秒,而且msxml的xpath速度很快,后来专门为此写了JNI处理xml的。

6架构师是优秀的沟通人员。
架构师一定要会忽悠,至少要扯淡。架构师不但要指导本部门员工的工作,也要协调其他部门的资源,还要向用户收集需求,制定规格说明书,重要的把用户的不合理要求砍掉,合理需求遵循自己的思路

posted @ 2012-03-19 02:21 paulwong 阅读(293) | 评论 (0)编辑 收藏

activiti5.6安装实战

如下是在window win7旗舰版环境下使用mysql数据库的安装实录:

一)下载 activiti-5.6.zip(http://activiti.org/downloads/activiti-5.6.zip


二)将activiti-5.6zip解压到指定目录,假设为“D:\activiti”,注意下面提到的路径均是相对于该路径而言


三)修改数据库类型为mysql

打开文件“setup\build.properties”修改db=mysql(默认为h2)。


四)配置mysql数据库

创建名称为activiti的空数据库,url要改为:“jdbc:mysql://localhost:3306/activiti?autoReconnect=true&amp;useUnicode=true&amp;characterEncoding=UTF-8&amp;useServerPrepStmts=true“,否则报编码错误,连接帐号设为activiti,密码也设为activiti。(如果不喜欢默认的连接配置,可以修改文件“setup\build.mysql.properties”中相应的属性值)


五)预下载一些必需的文件到“C:\downloads”

“D:\downloads”这个路径是在build.properties中通过属性“downloads.dir”定义的,也可以手动修改指定其他位置(默认值为:downloads.dir=../../downloads)。

如果确保网络环境很顺畅,这一步也可以不做,安装脚本会自动下载,由于之前的版本我安装时经常下载中断,导致文件损坏、安装异常,所以我习惯了先预先下载,保证安装顺畅点。主要下载如下2个文件,左侧为下载地址,右侧为下载后保存的文件名:


1) http://mirrors.enquira.co.uk/apache/apache-tomcat-6.0.29.zip –> apache-tomcat-6.0.29.zip (2.71MB)

若有tomcat可以不用下载,将tomcat复制到该目录下,如果tomcat的版本不是6.2.29则需要修改setup\build.properties文件中的tomcat.version=6.0.xx

修改为当前的tomcat版本


2) http://activiti.org/downloads/activiti-modeler-5.6.war –> activiti-modeler-5.6.war (31.8MB)

此war文件就是activiti演示的web程序war包必须下载。


3)为了改变演示安装里KickStart使用的数据库,产生一个新的activiti.cfg.jar,并将它放置到apps/apache-tomcat-6.x/webapps/activiti-kickstart/WEB-INF/lib文件夹。 


4)将JDBC DRIVER JAR拷贝到setup\files\dependencies\libs中,并将类似libs.webapp.administrator的所有配置文件中如有对H2JAR引用的都增加对JDBC DRIVER JAR的引用


六)修改浏览器的可执行文件路径

 

打开文件“setup\build.xml”修改属性windows.browser的值为浏览器的启动文件对应的位置。如我一直使用chrome,配置如下:

<property name=”windows.browser” value=”C:/Documents and Settings/dragon/Local Settings/Application Data/Google/Chrome/Application/chrome.exe” />

修改这个的目的是方便下面的”ant demo.start”结束后自动打开浏览器访问相关演示模块的首页。

注:在我的win7下系统上,使用chrome浏览器配置成了C:/Users/Administrator/AppData/Local/Google/Chrome/Application/chrome.exe但是在demo.start启动后没有打开浏览器,配置成Firefox浏览器启动路径也没有生效,原因有待查明中。


七)检查一下你的电脑是否已经使用了tomcat服务

如果使用了tomcat服务,得停掉,否测会冲突。顺便检查一下8080端口有没有被占用,否测也会冲突导致安装失败。


八)安装ant1.7和jdk1.5+环境

主要是设置环境变量ANT_HOME和JAVA_HOME,并将%ANT_HOME%\bin、%JAVA_HOME%\bin设置到path环境变量中。


九)一切就绪后就可以开始体验了

命令行切换到“setup/”,运行”ant demo.start”,等待整个安装过程自动完成吧,安装完毕后默认会自动打开浏览器。若没有启动浏览器,需自己手动打开浏览器在地址栏中输入访问地址。

可访问web应用如下:

Web应用名称 URL 描述
Activiti Probe http://localhost:8080/activiti-probe/ 管理员管理控制台。利用此工具可以查看配置的流程引擎是否被正确初始化了,以及数据库表的内容。
Activiti Explorer http://localhost:8080/activiti-explorer/ 流程引擎控制台。利用此工具可以浏览个人以及候选任务列表,然后完成任务。
Activiti Cycle http://localhost:8080/activiti-cycle/ Activiti协作工具。利用此工具可以浏览仓库及在模型格式间执行切换
Activiti Modeler powered by signavio http://localhost:8080/activiti-modeler/p/explorer 基于web的流程设计工具。利用此工具进行以图形化的方式编写复合bpmn2.0的流程定义文件。
Activiti Kickstart http://localhost:8080/activiti-kickstart 允许以临时的方式来快速而高效地指定流程。使用KickStart可以快速创建简单流程、快速原型以及临时的工作流。
Activiti Administrator http://localhost:8080/activiti-administrator 用于管理用户和用户组的web应用程序。目前它只是被当作独立的应用程序,但我们打算根据许可将有些web应用程序统一成一个web应用程序。

演示用户

用户Id 密码 角色
Kermit Kermit 管理员
gonzo gonzo 经理
fozzid fozzid 用户


十)新建一个流程并演示。

访问:http://localhost:8080/activiti-modeler/

访问后会看到左侧菜单栏中是当前workspace中自带的一些示例流程。


点击上方菜单new->Business process diagram菜单项,浏览器会打开activiti建模器

如图,此图中描述了一个编写每月财务报告—>审批财务报告的简单流程。(此处用自带的FinancialReportProcess流程做演示)

图中看到的是一个 none start event (左边的圆圈),其次是两个 user tasks撰写财务报告批准财务报告,以 none end event (右边边框加粗型的圆圈) 结束。

  • none start event 让我们认识到要开始一个流程。
  • user tasks 声明一个基于用户操作的流程任务. 注意第一个任务是分派用户组 accountancy 的, 而第二个任务是分派到用户组management 的. 查看 分派用户任务章节 可以得到更多怎样分派任务到用户或组的信息。
  • 当到达 none end event 节点后流程就结束。

以用户fozzie(他是一个会计师)身份登录到Activiti Explorer(http://localhost:8080/activiti-explorer/),选择PROCESSES页签,在列表的Action列中点击流程“Monthly financial report’”的“Start Process”链接来启动一个流程实例。如下图所示:


由于我们是以用户fozzie登录,故在我们启动了这个流程实例后,可以看到一个新的候选任务。我们这是切换到TASKS页签页去看看这个新任务(如下图),可以发现就算其他人启动的流程实例,所有属于用户组accountancy的用户都可以看到这个新的候选任务。


领取任务:

通过Activiti Explorer界面点击claim按钮将执行相同的领取任务操作。现在这个任务将显示在任务领取者的个人任务列表中,领取任务后,可以在my tasks中查看并点击页面上的complete按钮提交。


现在注销掉fozzi用户并以kermit(他是管理者)用户登录,第二个任务现在就显示在待指定任务列表中了。Kermit用户和上一步的操作一样,可以对该任务进行领取和提交,至此,该流程就走完了。如下图所示:

 


我在安装使用过程中遇到如下一些问题:

1)activiti-modeler-5.6.war不会自动发布,导致访问不了

解决办法:自己将activiti-modeler-5.6.war手工解压到apps\apache-tomcat-6.0.29\webapps\activiti-modeler,并删除apps\apache-tomcat-6.0.29\webapps\activiti-modeler-5.6.war


2)tomcat控制台显示的中文乱码

解决办法:修改文件apps\apache-tomcat-6.0.29\conf\logging.properties,增加如下一行的配置:

java.util.logging.ConsoleHandler.encoding = GBK


3)使用activiti-modeler保存流程图前后台均会报错

解决办法:创建目录apps\apache-tomcat-6.0.29\endorsed,并将jar文件”apps\apache-tomcat-6.0.29\webapps\activiti-modeler\WEB-INF\lib\jaxb-api.jar”复制到该目录下。


4)第一次安装后,新建流程中出现中文会出错,网上找了下没有找到解决方法,我又重新安装了一遍,没有该问题了,目前尚不清楚是由何引起的。

 

安装eclipse designer插件:

需要eclipse版本为:Eclipse IDE for java EE developers(Helios Service)

打开Help->Install New software。在如下面板中,点击Add按钮,然后填写下列字段:

Name: Activiti BPMN 2.0 designer

Location: http://activiti.org/designer/update/


添加完成后,eclipse会搜索到BPMN designer插件,选中后,按提示操作完成即可。

由于是在线安装,插件可能偏大,我在安装的过程中等待了很长时间,大约半个小时,所以如果安装此插件请耐心等待。

安装完成后,重启eclipse, 导入activiti自带的examples,在src/main/process/路径下,随便找个后缀名为bpmn20.xml的文件打开,就可以看到该插件的效果了,如图:


终于安装完成了,总结一下,在安装过程中,遇到了或多或少的问题,发现activiti的用户数不是那么多,因为好多问题网络上都搜索不到解决办法,都得自己再钻研一下,很是痛苦,不知啊现在国内有那个项目用activiti5的成功经验是否可以拿出来分享一下。

posted @ 2012-03-19 00:19 paulwong 阅读(15795) | 评论 (3)编辑 收藏

ACTIVITI WEB DESIGNER

  1. 下载代码:http://signavio-core-components.googlecode.com/svn/trunk

  2. 修改build.properties
    # This is the Signavio Core Components configuration file. Most users only have to configure this file.

    # The path to your Apache Tomcat webapps folder这里就是生成WAR后,会自动拷贝过去的目录
    dir-tomcat-webapps 
    = /apache-tomcat-6.0.16/webapps

    # The path to your jBoss deployment folder
    dir-jboss-webapps 
    = /jboss-5.1.0/server/default/deploy

    # The folder the war file(s) is/are stored
    target 
    = target

    # The version of the application. If you want to integrate the Signavio Core Components into
    #  your own software product
    , you can align the version number.
    version
    =5.0-SNAPSHOT

    # The name of the war file
    , if you use the all-in-one-war build target
    war 
    = activiti-modeler

    # The configuration you want to use. This is the name of the folder in the 'configuration' project
    #  that contains the configuration and skin files. The following configurations are available:
    #  default
    , Activiti, jBPM
    #  You can also add your own configuration in the 'configuration' project.
    configuration 
    = Activiti

    # The URL of your server. Format: http(s)://<domain>(:<port>)这里要填实际的IP
    #  Do not add a trailing slash here!
    host 
    = http://10.5.12.248:8180/

    # The path on your system the directories and diagram files are created.这里就是图形文件保存的地方
    # Do not use \ ! Always use / !
    fileSystemRootDirectory 
    = ../../../workspace/activiti-modeler-examples

  3. 要特别注意编码,否则会编译失败,修改EDITOR中的build.properties
    <java dir="${build}" jar="${root}/lib/yuicompressor-2.4.2.jar" fork="true" failonerror="true" output='${compress.temp}'>
        <!-- add a row as follow --> 
        <sysproperty key
    ="file.encoding" value="UTF-8"/> <arg file='${build}/oryx.debug.js' /> 
    </java>

  4. 运行命令
    ant build-and-deploy-all-in-one-war-to-tomcat

  5. 打开浏览器输入网址:http://10.5.12.248:8180/activiti-modeler即可

posted @ 2012-03-16 11:37 paulwong 阅读(2845) | 评论 (2)编辑 收藏

activiti 5.4 demo基于oracle数据库安装配置

一、环境下载
  1. Activiti5.4.zip
  2. activiti-modeler-5.4.war
  3. apache-tomcat-6.0.20.zip
  4. jdk 1.6full22
  5. ant1.8.2
  6. oracle 10g rc2

二、环境准备
  1. 安装jdk1.6full22 配置JAVA_HOME,CLASS_PATH,PATH
  2. 安装ant1.8.2,配置ANT_HOME,PATH
  3. 安装oracle 10g rc2,创建用户:activiti/activiti(建议为其创建独立表空间和临时表空间),分配create session,resource,dba权限;
  4. 解压Activiti5.4.zip->../activiti-5.4(即activiti_home)
  5. 将activiti-modeler-5.4.war和apache-tomcat-6.0.20.zip放到activiti_home/downloads

三、activiti5.4 demo相关配置
  1. 指定demo数据库为oracle 10g
    修改activiti_home/setup/build.properties:db=H2->db=oracle

  2. 指定自选版本的tomcat(建议6.0以上,这里用的是6.0.2.0,以下为测试过)   
    修改activiti_home/setup/build.properties:tomcat.version=6.0.32->tomcat.version=6.0.2.0

  3. 指定自己下载的activiti-modeler-5.4.war和apache-tomcat-6.0.20.zip(这里必须与tomcat.version一致) 
    修改downloads.dir=../../downloads->downloads.dir=activiti_home/downloads

  4. 配置oracle数据库信息,主要修改activiti_home/setup/build.oracle.properties:       
    db=oracle
    jdbc.driver
    =oracle.jdbc.driver.OracleDriver
    jdbc.url
    =jdbc:oracle:thin:@localhost:1521:ORCL
    jdbc.username
    =activiti
    jdbc.password
    =activiti


  5. 修改tomcat的8080为80端口,主要修改activiti_home/setup/build.xml配置(两处):
    <replacetoken><![CDATA[port="8080"]]></replacetoken>
    <replacevalue><![CDATA[port="80" URIEncoding="UTF-8"]]></replacevalue>
    注意:如果修改了默认端口,需要修改配置文件里所有默认端口为指定端口

  6. 指定自己的浏览器,这里用的是firefox,如果配的浏览器不存会取当前系统默认浏览器
    <property name="windows.browser" value="F:/application/Mozilla Firefox/firefox.exe" />


  7. 指定自己数据库对应的jdbc driver默为ojdbc5*.jar,这里指为ojdbc14.jar,修改如下:
    <include name="ojdbc1*.jar" if="db.is.oracle"/>

    并把ojdbc14.jar放到:activiti_home/setup/files/dependencies/libs和activiti_home/setup/files/webapps所有web工程对应的lib里(这个在安装发布相应工程为自动复制到相应的应用里)

  8. 解决安装过程中中文显示乱码问题(这里不能解决安装一小段显示乱码问题),在activiti_home/setup/files/tomcat/logging.properties添加如下内容:
    java.util.logging.ConsoleHandler.encoding = GBK

  9. 在activiti_home/setup运行ant cfg.create命令生成修改后的activti配置,这些信息都放在新生成的activiti_home/setup/build文件里
    这里最关键的两个文件:activiti.cfg.xml和activiti-cfg.jar

  10. 替换activiti_home/setup/files/cfg.activiti/standalone/activiti.cfg.xml为新生成的activiti.cfg.xml

  11. 替换activiti_home/setup/files/webapps下所有activiti-cfg.jar为新生成的activiti-cfg.jar

  12. 修改activiti_home/setup/files/cfg.modeler/configuration.properties里host = http://localhost:8080为host = http://localhost(这里用的是80端口)

    

posted @ 2012-03-14 15:19 paulwong 阅读(5161) | 评论 (0)编辑 收藏

Web工作流设计器

http://www.duobee.com/demos/workfloweditor.html

posted @ 2012-03-11 21:46 paulwong 阅读(622) | 评论 (0)编辑 收藏

一张业务表用于多个业务流程

在工作流管理系统中,通常是先给业务流程建模,利用流程设计器,将业务的办理过程用流程支持的节点方式表示出来。



 

业务建模之后,再确定每个节点上办理的业务,办理业务的过程,通常是以填写完业务表单的方式来完成的。所以需要分析每个节点上填写的表单内容,根据 表单内容建立业务表,表字段等。再将字段绑定到表单中录入控件上,将表单录入的数据保存到数据库中,这样业务表单模块就完成了。



 

 



 

业务表单完成之后,再挂接到流程节点上。



 

 

另外可能需要再次完善一下流程节点的一些属性,如增加每个节点的指定办理人。

设置取业务表中的一些关键值用于流程中,如取报销单中的报销金额,请假单的请假天数,用于流程上下文中做条件使用。

最后,在业务表中,需要增加一个流程实例id字段,用于和业务流程关联。在启动业务流程的时候,需要将获得的流程实例id写入这个字段中,使得业务记录能和流程实例关联上。


通过上面这些步骤,就建立好了业务流程了,可以启动流程实例,办理业务了。业务的流转就按照流程建模中定义好的顺序办理,不需要再在业务表 中增加状态字段来控制业务的流转了。业务的办理过程变得有迹可循了,每个流程实例均可以列出运行的轨迹图,或者列表出运行的轨迹。每个节点上办理的业务也 能通过查询业务表单再次展现。

 

上面我们说过,业务表是存储办理业务数据的数据库表,一般来说,一个业务表只用于一种业务流程中,存储同一类型的业务数据。当流程运行结束的时候, 这些业务数据就被封存,不能在流程的节点中再次被编辑和修改。(除非直接开库修改数据,或者另外做一些模块,直接修改业务数据)

 

但是,这些封存的业务数据,有可能会被再次启用投入到另外一个业务流程中去使用,这种需求可能是需求肯定是有应用场景的,不管是分段的处理过程还是后期又做的一些业务补充等,都有可能发生。

 

如果一个业务表,需要再次用于另外一个业务流程当中,则我们只需要给业务表,再增加一个流程实例id字段,就可以了,再次新启动的业务流程获得的流 程实例id就写入这个新的流程实例id字段。和以前的那个流程实例id不相关了。只是如果是编辑同一条业务记录的话,就可能把上次的数据给修改了。这样理 论上是可以支持n个业务流程。

 



 


总结一下,一个业务表用于一个业务流程中,用一个流程实例id字段和流程关联,用于另外一个业务流程中,则再建一个流程实例id字段和流程实例关联。

 

一个业务流程可能会涉及到多张业务表,一张业务表也可能涉及到多个业务流程。

posted @ 2012-03-06 18:02 paulwong 阅读(345) | 评论 (0)编辑 收藏

Java MVC框架性能比较

现在各种MVC框架很多,各框架的优缺点网络上也有很多的参考文章,但介绍各框架性能方面差别的文章却不多,本人在项目开发中,感觉到采用了struts2框架的项目访问速度,明显不如原来采用了struts1框架的项目快,带着这些疑惑,我对各类MVC框架的做了一个简单的性能分析比较,其结果应该说是基本符合预期的,可供大家参考。

测试环境:

CPU:酷睿2 T5750,
内存:DDR2-667 2G,
Web容器:Tomcat6.0,最大线程数设置为1000,
操作系统:WinXP-sp3

测试步骤:

搭建6个Web工程,如下:
1.纯JSP:不包含任何MVC框架,只有一个测试用的JSP页面。
2.struts1:包含一个Action,不做任何逻辑处理,直接转发到一个JSP页面
3.struts2 JSP:不包含Action,只包含测试JSP页面,直接访问该页面。
4.struts2 单例Action:采用Spring来管理Struts2的Action实例,并配置成单例模式。
5.struts2 多例Action:采用Spring来管理Struts2的Action实例,并配置成单例模式。
6.SpringMVC3:采用Spring来管理Controller实例,包含一个Controller,不做逻辑处理,收到请求后,直接返回到一个JSP页面。

测试结果:

测试工程 请求数 并发数 总时间(s) 总时间(s) 总时间(s) 平均值(s) Requests Per Second(每秒处理请求数)
JSP 2000 200 5.55 3.59 4.11 4.42 452.83
struts1 2000 200 6.77 3.83 7.00 5.86 341.03
struts2 JSP 2000 200 25.20 26.30 24.11 25.20 79.35
struts2 单例Action 2000 200 28.36 27.59 27.69 27.88 71.74
struts2 多例Action 2000 200 31.31 31.97 39.56 34.28 58.34
SpringMVC3 2000 200 7.16 7.50 4.27 6.31 317.09

说明:

以上测试虽不是非常的精确,但基本能说明一定的问题。每个JSP页面和Action都不包含任何的业务逻辑代码,只是请求转发。每轮测试取三次总时间的平均值。所有工程的测试均全部完成并正常处理请求,没有请求拒绝情况发生。

结论:

  1. 纯JSP的性能应该最高,这不难理解,JSP被编译成Servlet后,没有任何多余的功能,收到请求后直接处理。(这也验证一句经典的话:越原始效率就越高。

  2. struts1的性能是仅次于纯JSP的,由于struts1采用单例Action模式,且本身的封装相比struts2应该说简单很多,虽然开发效率不如struts2,但已经过多年的实践考验,性能稳定高效。

  3. 相比来说struts2的性能就比较差了,这不难理解,struts2之所以开发方便,是由于采用值栈、OGNL表达式、拦截器等技术对请求参数的映射和返回结果进行了处理,另外还采用大量的标签库等,这些都无疑增加了处理的时间。因此降低了效率。在我们实际的项目中,我测试本地工程访问每秒处理请求数只能达到35左右,应该说还有不少可优化的空间。

  4. 很多人认为struts2性能差是因为它的多例Action模式导致的,但我们采用spring管理struts2的Action,并设置按单例方式生成Action实例后,发现其性能有所提高,但并不是很明显。由此可见,多例Action模式并不是struts2性能瓶颈所在。另外,我们在struts2中采用JSP方式访问,发现其性能依旧和没有采用任何MVC框架的纯JSP之间存在好几倍的差距,这又从另一个侧面证实了我们刚才得出结论,struts2性能的瓶颈不在于它的多例Action模式。

  5. SpringMVC3的性能略逊于struts1,但基本是同级别的,这让人眼前一亮,springMVC有着不比struts2差的开发效率和解耦度,但性能却是struts2的好几倍,这让我们灰常振奋,SpringMVC无疑又是项目开发的一个好的选择。

posted @ 2012-03-03 16:13 paulwong 阅读(1548) | 评论 (0)编辑 收藏

仅列出标题
共114页: First 上一页 85 86 87 88 89 90 91 92 93 下一页 Last