<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
  <channel>
    <title>fly_ever</title>
    <description></description>
    <link>http://fly-ever.javaeye.com</link>
    <language>UTF-8</language>
    <copyright>Copyright 2003-2008, JavaEye.com</copyright>
    <docs>http://blogs.law.harvard.edu/tech/rss</docs>
    <generator>JavaEye - 做最棒的软件开发交流社区</generator>
      <item>
        <title>liferay的js加载问题深度分析</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/202532" style="color:red;">http://fly-ever.javaeye.com/blog/202532</a>&nbsp;
          发表时间: 2008年06月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          今天遇到liferay一个很郁闷的问题<br /><strong><span style="font-size: large">问题描述</span></strong><br />在开发环境中，直接访问liferay系统，没有问题。<br />在运行环境中，经过一个中间系统转发，通过https来访问liferay系统，结果页面上出现很多js错误，并且有些功能不能使用。<br /><span style="font-size: large"><strong>解决思路</strong></span><br />经过对页面的分析，发现页面存在css和js文件的缺失。<br />有点莫名其妙～～<br />比较两个环境，发现之后的环境与之前环境的区别为：经过了一次转发，以及使用了https。<br />确定是这个环境使访问liferay时缺失了某些js和css文件。<br />立即想考虑liferay是如何加载js和css文件的。<br />后来想到在配置文件中有网页内容传输以及js的相关配置，想试试对配置进行修改。<br />最后定位下来，是portal.properties下的属性 javascript.fast.load 在起作用。<br />设置 javascript.fast.load=false即可。<br />  <br />    #<br />    # Set this property to true to load the combined JavaScript files from the<br />    # property "javascript.files" into one compacted file for faster loading for<br />    # production. Set this property to false for easier debugging for<br />    # development. You can also disable fast loading by setting the URL<br />    # parameter "js_fast_load" to "0".<br />    #<br />    javascript.fast.load=false<br />该属性的含义：设置该属性为true，属性javascript.files中指定的js文件集将整合到一个文件中，进行压缩，然后加载，这样就能更快的加载。<br />如果设置为false，更容易在开发中进行调试。<br />也可以设置URL参数js_fast_load 为0，就不会快速加载。<br /><br /><strong><span style="font-size: large">深入分析</span></strong><br />为了更具体比较把该参数设置为false之后的区别，<br />分别保存下设置为true和false之后的同一个页面。<br />发现设置为false时，在保存的那个页面文件夹中多了很多js文件。<br />仔细比较下载下来的js文件名称：<br />当设置为true时，下载了5个js文件。everything_packed.js文件的大小为4M多。<br />当设置为false时，下载了43个js文件，包含上述5个中的四个js，除了everything_packed.js。<br /><br />跟踪加载js的过程：<br />首先查看处理js相关的文件：<br />1，在portal.properties中的js相关设置：<br />    javascript.files=\        设置js文件列表；<br />    javascript.fast.load=false<br />2，类com.liferay.portal.tools.JavaScriptBuidler中：<br /> 把javascript.files中的js文件列表合并到一个文件mergedFile中<br /><pre name="code" class="java">
	public JavaScriptBuilder(String jsDir, String mergedFile) {
		try {
			StringMaker sm = new StringMaker();

			String[] files = PropsUtil.getArray(PropsUtil.JAVASCRIPT_FILES);

			for (int i = 0; i &lt; files.length; i++) {
				String content = FileUtil.read(jsDir + files[i]);

				sm.append(content);
				sm.append("\n");
			}

			FileUtil.write(mergedFile, sm.toString());
		}
		catch (Exception e) {
			e.printStackTrace();
		}
	}
</pre><br />3，页面  /html/common/themes/top_js.jsp中：<br />该页面判断属性javascript.fast.load值，并根据取值分别处理。即设为true的时候，只需要加载everything.packed.js文件，当设为false时，则循环加载属性javascript.files中设置的文件列表。<br /><pre name="code" class="html">
&lt;c:choose>
	&lt;c:when test='&lt;%= ParamUtil.getBoolean(request, "js_fast_load", PropsValues.JAVASCRIPT_FAST_LOAD) %>'>

		&lt;%--
		everything_packed.js includes all of the JavaScript files. It is
		autogenerated with the Ant build-javascript task.
		--%>

		&lt;script src="&lt;%= themeDisplay.getPathJavaScript() %>/everything_packed.js?bn=&lt;%= ReleaseInfo.getBuildNumber() %>" type="text/javascript">&lt;/script>
	&lt;/c:when>
	&lt;c:otherwise>

		&lt;%
		String[] javaScriptFiles = PropsUtil.getArray(PropsUtil.JAVASCRIPT_FILES);

		for (int i = 0; i &lt; javaScriptFiles.length; i++) {
		%>

			&lt;script src="&lt;%= themeDisplay.getPathJavaScript() %>/&lt;%= javaScriptFiles[i] %>?bn=&lt;%= ReleaseInfo.getBuildNumber() %>" type="text/javascript">&lt;/script>

		&lt;%
		}
		%>

	&lt;/c:otherwise>
&lt;/c:choose>
</pre><br />4，再看ant文件，portal-web/build.xml：<br />在部署时，把设置的js文件列表合并到文件everything_unpacked.js中，然后使用压缩处理类，压缩成文件everything_packed.js。<br /><pre name="code" class="xml">
	&lt;target name="build-javascript">
		&lt;java
			classname="com.liferay.portal.tools.JavaScriptBuilder"
			classpathref="project.classpath"
			fork="true"
			newenvironment="true"
		>
			&lt;arg value="docroot/html/js/" />
			&lt;arg value="docroot/html/js/everything_unpacked.js" />
		&lt;/java>
		&lt;antcall target="build-javascript-cmd">
			&lt;param name="js.from.file" value="docroot/html/js/everything_unpacked.js" />
			&lt;param name="js.to.file" value="docroot/html/js/everything_packed.js" />
		&lt;/antcall>
	
		&lt;target name="build-javascript-cmd">
		&lt;java
			classname="com.yahoo.platform.yui.compressor.YUICompressor"
			classpathref="project.classpath"
			fork="true"
			newenvironment="true"
		>
			&lt;arg line="--type js -o ${js.to.file} ${js.from.file}" />
		&lt;/java>

		&lt;!--
		http://dean.edwards.name/download/#packer
		http://homepages.nildram.co.uk/~9jack9/download/packer.wsh.zip
		-->

		&lt;!--&lt;exec executable="cmd">
			&lt;arg line="/c CScript /nologo ${project.dir}/tools/pack.wsf ${js.from.file} > ${js.to.file}" />
		&lt;/exec>-->
	&lt;/target>
</pre>	<br /><strong><span style="font-size: large">结论</span></strong><br />由上面文件即可得出对js的处理流程：<br />在部署时，运行ant->build.xml->com.liferay.portal.tools.JavaScriptBuilder,进行压缩处理，文件生成到目录docroot/html/js/everything.packed.js。<br />页面展示时，页面/html/common/themes/top_js.jsp根据配置信息加载js文件。<br /><br /><strong><span style="font-size: large">存在的问题</span></strong><br />这个过程中，还有一个疑问：在服务器目录下看到的everything.packed.js文件大小只有301k。<br />但是下载下来的页面，包含的everything.packed.js文件大小有4.52M。<br />因此下载下来的js并不是服务器目录上的那个everything.packed.js文件。
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/202532#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 12 Jun 2008 16:14:27 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/202532</link>
        <guid>http://fly-ever.javaeye.com/blog/202532</guid>
      </item>
      <item>
        <title>liferay的过滤器</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/200444" style="color:red;">http://fly-ever.javaeye.com/blog/200444</a>&nbsp;
          发表时间: 2008年06月05日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          liferay4.3.3中的过滤器：<br />这些过滤器基本上在属性文件中有对应的属性，通过设置这些属性值来确定是否执行过滤器中的操作。<br />其中有一些过滤器是用来提高系统性能的。如：<br />com.liferay.filters.compression.CompressionFilter，<br />com.liferay.portal.servlet.filters.layoutcache.LayoutCacheFilter，<br />com.liferay.filters.strip.StripFilter。<br />了解这些过滤器的功能，对于一些根本不会用的的过滤器，我们完全可以在web.xml<br />中屏蔽掉过滤器的map设置。这样也可以提高系统性能。如以下过滤器，系统中不会用到。<br />com.liferay.portal.servlet.filters.sso.cas.CASFilter，<br />com.liferay.filters.doubleclick.DoubleClickFilter，<br />com.liferay.filters.header.HeaderFilter，<br />com.liferay.portal.servlet.filters.sso.ntlm.NtlmFilter，<br />com.liferay.filters.secure.SecureFilter，<br />com.liferay.portal.servlet.filters.sessionid.SessionIdFilter。<br /><br />以下为所有过滤器：<br />com.liferay.portal.servlet.filters.autologin.AutoLoginFilter:检查登录用户的用户名称是否为空，为空则重定向。<br />com.liferay.portal.servlet.filters.sso.cas.CASFilter：如果cas.auth.enabled设置为true ,则处理该filter。单点登录<br />com.liferay.filters.compression.CompressionFilter:如果属性com.liferay.filters.compression.CompressionFilter=true，则处理http内容的压缩。这样可以使系统更快。<br />											<br />com.liferay.filters.doubleclick.DoubleClickFilter：如果属性com.liferay.filters.doubleclick.DoubleClickFilter=true，则处理在服务器端阻止鼠标双击。											<br />com.liferay.filters.header.HeaderFilter：添加页面过期时间的参数，根据filter config属性文件中的Expires。<br />com.liferay.portal.servlet.filters.layoutcache.LayoutCacheFilter：属性    com.liferay.portal.servlet.filters.layoutcache.LayoutCacheFilter=true时，开启运行时layout Cache.<br />com.liferay.portal.servlet.filters.sso.ntlm.NtlmFilter: 如果ntlm.auth.enabled=true,则处理该filter。单点登录<br />com.liferay.filters.secure.SecureFilter：安全，走https：//<br />com.liferay.portal.servlet.filters.sessionid.SessionIdFilter:如果    com.liferay.portal.servlet.filters.sessionid.SessionIdFilter=true，保证只一个session创建，在http和https之间。<br />com.liferay.filters.strip.StripFilter：如果    com.liferay.filters.strip.StripFilter=true，执行，去掉空行，加快页面的展示速度。<br />										<br />com.liferay.portal.servlet.filters.velocity.VelocityFilter：如果    com.liferay.portal.servlet.filters.velocity.VelocityFilter=false，处理    # The Velocity filter will process */css/main.css as a Velocity template.<br />com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter：   		<br />    #<br />    # The virtual host filter maps hosts to public and private pages. For<br />    # example, if the public virtual host is www.helloworld.com and the friendly<br />    # URL is /helloworld, then http://www.helloworld.com is mapped to<br />    # http://localhost:8080/web/helloworld.<br />    #<br />    com.liferay.portal.servlet.filters.virtualhost.VirtualHostFilter=true
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/200444#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 05 Jun 2008 11:30:32 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/200444</link>
        <guid>http://fly-ever.javaeye.com/blog/200444</guid>
      </item>
      <item>
        <title>使用liferay开发小记</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/177836" style="color:red;">http://fly-ever.javaeye.com/blog/177836</a>&nbsp;
          发表时间: 2008年03月30日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          使用liferay开发系统时涉及到的对liferay的一些修改信息：<br />liferay版本4.3.3<br />1，系统不想使用liferay默认的能自己定制portlet外观信息的选项。<br />则修改liferay-portal\html\themes\_unstyled\templates下的portlet.vm，并且在<br />相应的各个风格下面也修改该文件，去掉文件中的$theme.iconConfiguration()。<br />则在每个portlet上不再有外观样式设置的选项。<br />2，在对个人或者对社区的页面进行设置时，会发现页面类型。该页面类型由portal.properties属性文件的layout.types属性设定。<br />3，想去掉我的帐户链接，则可以<br />	修改\html\themes\_unstyled\templates\init.vm文件，去掉我的帐户相关内容。<br />4，页面设置中很多功能需要屏蔽掉，修改<br />/portlet/communities/edit_pages.jsp文件即可。<br />5,如果想用外观样式功能，但想修改配置界面的内容，则可以按自己需要修改<br />\html\portlet\portlet_css\view.jsp该页面。<br />6，风格只保留一个.不要其他风格。<br />修改配置文件liferay-look-and-feel.xml<br />7，去掉公开页。保留我的公共(页面)，<br />修改页面：/html/taglib/ui/my_places/page.jsp，去掉公开页。去掉页面设置中的公开页设置。<br />8，在为liferay系统添加内容时，想要字体更大，添加内容的页面出现在页面中间。<br />则修改js文件，js/liferay/layout_configuration.js,修改toggle方法，width:400,noCeneter:false;这样可以使添加内容的页面显示在整个页面中间。<br />修改\html\portlet\layout_configuration中的view_category.jsp页面，则可以修改添加内容页面的显示内容和样式。<br />9，权限达到可看不可用的效果。<br />设置一些portlet的权限，使某些用户能看而不能添加。修改html\portlet\layout_configuration\view_category.jsp页面。<br />取得所有的portlet ,而不是用户有权限添加的portlet.<br />在展示用户添加portlet时，设置不可添加的portlet添加按钮不可用。<br />10，liferay系统中，如果不通过liferay而修改数据库中的数据，则在liferay系统中不能看到实时更新的效果，因为liferay采用缓存机制。<br />需要修改持久实现类<br />service.persistence.××××PersistenceImpl中的对应方法，使用直接查询，而不采用读取缓存的操作，这样才能得到实时更新的数据。<br />去掉：<br />        <pre name="code" class="java">Object result = FinderCache.getResult(finderClassName,
                finderMethodName, finderParams, finderArgs, getSessionFactory());
        FinderCache.putResult(finderClassName, finderMethodName,
                    finderParams, finderArgs, list);</pre><br />在对持久化对象进行更新操作时，会调用下面的代码，所以可以保持在缓存中的对象是最新的。<br />            <pre name="code" class="java">FinderCache.clearCache(AICustomerReports.class.getName());</pre>
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/177836#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sun, 30 Mar 2008 20:56:11 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/177836</link>
        <guid>http://fly-ever.javaeye.com/blog/177836</guid>
      </item>
      <item>
        <title>liferay的权限实践</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/145846" style="color:red;">http://fly-ever.javaeye.com/blog/145846</a>&nbsp;
          发表时间: 2007年12月04日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <span style="font-size: 16pt">Liferay的权限结构（liferay版本4.3.3）</span><br />Liferay能对每个具体的portlet进行控制，也能对portlet内的实体对象进行权限控制。<br />Liferay中进行管理的资源分为两种：<br />Portlet资源和model资源。<br />通过liferay的管理portlet就可以可视化的实现portlet的权限管理。<br />如果要对portlet内的实体对象model进行管理，需要进行一些程序实现。<br />现以一个具体的实例来说明如何实现portlet内的model资源的权限管理：<br />一个报表的portlet，其中包含一个具体的报表列表。我们需要对每个具体报表进行权限控制。<br /><span style="font-size: 16pt">建表</span><br />首先报表需要保存在数据库中，为报表建立报表数据库。根据liferay的开发过程，步骤如下：<br />在ext-impl文件夹下，新建service.xml，该xml文件描述报表数据表的字段信息，并指定对应的java对象。设定&lt;entity name="AIReports" local-service="true"><br />进入ext-impl目录，执行命令：ant build-service。<br />自动生成建表的sql语句，在ext\sql\portal-tables.sql中。Copy该语句并执行，生成对应的表。 <br />之后，liferay自动生成相应的java类和接口，根据xml文件的描述不同，生成的类会有差别，主要有如下类：<br />实体类，Reports<br />持久类，ReportsPersistence，ReportsPersistenceImpl,ReportsUtil。<br />LocalService类，ReportsLocalServiceImpl,ReportsLocalService,<br />ReportsLocalServiceUtil。.<br />Service类，ReportServiceImpl,ReportsService,ReportServiceUtil。<br /><span style="font-size: 16pt">配置权限</span><br />针对portlet和报表对象，进行权限声明。<br />在ext-impl\resource-actions目录下，建立report.xml文件。<br />在该文件中，配置resource-action-mapping中的portlet-resource和<br />model-resource.。<br />并向系统指明该文件的位置。在ext-impl\portal-ext.properties中指明属性resource.actions.configs=<br />resource-actions/default.xml,resource-actions/default-ext.xml。<br />并在resource-actions/default-ext.xml文件中，指明<br />&lt;resource file="resource-actions/yjreport.xml" /><br /><span style="font-size: 16pt">实现具体权限</span><br />根据model-resource中声明的权限，在类中具体实现。针对声明的ADD,DELETE和PERMISSIONS权限，<br />在类ReportLocalServiceImpl中实现相应的方法。<br />进入ext-impl目录，执行ant build-service，为实现的方法生成对应的接口和工具类静态方法<br /><span style="font-size: 16pt">权限验证</span><br />当权限实现后，会在操作时进行验证。验证分两部分，前台页面的按权限展现和后台执行功能时的验证。<br />并且对于portlet得验证，可以直接调用liferay已经实现的权限助手类，对于portlet内的model资源，则需要自己实现权限助手类<br />ReportPermissions。<br />权限助手类包含两个方法,check和contains。<br />check方法适用于后台验证，contains方法适用于前台验证。<br />前台展现时的验证方法：在jsp页面中，如果要显示对应功能的展示按钮或链接时，调用权限验证的方法contains()。<br />后台实现功能时验证：ReportsServiceImpl类中的每个方法都调用相应的ReportsLocalServiceUtil中的方法，并且在调用之前执行验证方法check()，以实现功能的验证。
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/145846#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 04 Dec 2007 13:34:39 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/145846</link>
        <guid>http://fly-ever.javaeye.com/blog/145846</guid>
      </item>
      <item>
        <title>是liferay4.3.3的权限分配页面的bug吗？</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/143548" style="color:red;">http://fly-ever.javaeye.com/blog/143548</a>&nbsp;
          发表时间: 2007年11月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          liferay4.3.3分配权限时，如果只选择一条权限，则页面上通过箭头并不能把权限传递过来。是为什么呢？<br />
如图所示。<br />
但是如果我全部选定，然后再点箭头的话，可以传过来，但是会少一条数据。<br />
是liferay页面的BUG吧。<img src="C:\Documents and Settings\Administrator\桌面\liferay1.jpg" alt="" />
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/143548#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 26 Nov 2007 11:14:02 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/143548</link>
        <guid>http://fly-ever.javaeye.com/blog/143548</guid>
      </item>
      <item>
        <title>The Process Virtual Machine</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/85942" style="color:red;">http://fly-ever.javaeye.com/blog/85942</a>&nbsp;
          发表时间: 2007年06月02日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <br />
第一次翻译文章，其中还有很多错误以及语句不通顺的地方，还希望各位能够海涵，<br />
如果能够不吝指出我翻译中存在的问题，就是给我莫大的帮助。<br />
<font size="4" face="Times New Roman"><br />
Tom Baeyens:The Process Virtual Machine</font><br />
链接地址：http://www.theserverside.com/news/thread.tss?thread_id=45602<br />
<a href="http://www.onjava.com/pub/a/onjava/2007/05/07/the-process-virtual-machine.html" target="_blank">http://www.onjava.com/pub/a/onjava/2007/05/07/the-process-virtual-machine.html</a>?<br />
CMP=OTC-FP2116136014&amp;ATT=The+Process+Virtual+Machine<br />
<br />
几周前，Tom Baeyens 和Miquel Valdes Faura 在OnJava上写下了&ldquo;流程虚拟机&rdquo;。这个文章背后的想法是：<br />
在对一般的流程编码熟练之后，流程可以使用一般的描述结合具体的语言如jPDL,BPEL,page flow和其他已经实现的语言来描述。<br />
同样的，它反应了这个思想，就像JVM和各种已经在其上实现的语言：BPEL将会是一个在流程虚拟机上实现的流程语言。<br />
这是一个有趣的想法，给各种开发者提供了很多优势：既然它把开发者和业务分析者(流程语言最通常的受益者)作为目标对象，业务流程能被更多的人，使用在更多的领域，得到更好的结果。<br />
在很大程度上，web应用程序可以看作一个业务流程的例子。当这个业务流程在SEAM(并且，推测起来，web bean，不管怎样已经完成)中可用时，这个想法可以概括为消息队列，数据项目，工作流，全部的符号&mdash;&mdash;并且有一个流程虚拟机意味着开发者能轻易的得到业务流程而不需要精通整个抽象域。<br />
<strong><font size="4" face="Times New Roman"> 介绍：</font></strong><br />
这篇文章将展示业务分析人员和开发者如何受益于流程，业务流程管理和orchestration。我们将使用简单的术语解释核心的工作流引擎本质，以及在java环境中这个如何起到杠杆作用。每个好的开发者都知道数据库的关系模型，而工作流引擎缺少一个相应的模型，流程虚拟机将提供这缺失的一块。<br />
流程虚拟机是概念模型，应该是每个开发者的所有技能中的一项，因为它帮助解释所有变化的公开的工作流引擎。更进一步，因为Microsoft已经独立的达到了同样的方法(见下一个部分 另一边)，我们确信它将是下一代流程引擎的基础。这篇文章将清楚地显示这个目标和流程虚拟机的价值，并且指导你通过下面提及的流程虚拟机论文到达最重要的部分。你将也学习工作流技术是什么，什么时候在软件工程中它将有意义。<br />
文章中，工作流，BPM和orchestration相互之间的区别是不相关的，因此为了简单起见，我们将涉及到这些时都当作工作流。大多数工作流语言的目标是在工作流引擎中，长运行的流程能使用图形化的方式表达和执行。图形化的很大的优势是开发者和业务分析者能使用同一个语言。典型的工作流例子如：<br />
&nbsp;&nbsp;&nbsp; 保险索赔<br />
&nbsp;&nbsp;&nbsp; 支票记录<br />
&nbsp;&nbsp;&nbsp; 雇佣新员工<br />
但是工作流技术能应用在拥有状态机特征的软件的任何方面，如显示的以下这些额外的工作流例子：<br />
&nbsp;&nbsp;&nbsp; 定义一个粗糙的web服务作为其他web服务的一个功能<br />
&nbsp;&nbsp;&nbsp; 在web应用程序中，页面流描述页面间的导航<br />
&nbsp;&nbsp;&nbsp; 作业调度<br />
&nbsp;&nbsp;&nbsp; 信息队列orchestration<br />
传统的工作流引擎有一些瑕疵，在流程虚拟机中将得到解决：<br />
1&nbsp;&nbsp;&nbsp; 单一的集中在业务分析员。 传统的工作流系统有一个大的功能集中在图形化工具，这个做法意味着一个非技术人员能画一个业务流程图。然后工作流引擎将自动的提取该流程的软件支持信息。如果你考虑一下，你想把一个软件产品的创建由一个非技术人员来完成吗？流程虚拟机展示如何创建一个在业务分析员与开发者之间有效率的协作。能通过仅仅点击，编辑流程图形来实现的流程是非常有限的。除了这些，流程虚拟机也支持需要流程逻辑和流程代码的组合的大部分流程。<br />
2&nbsp;&nbsp;&nbsp; 流程引擎是与应用集成的系统的一个整体。这个使部署，测试和耦合使用应用程序事务的工作流事务很复杂。流程虚拟机允许工作流引擎能嵌入java应用程序或者能单独的部署。<br />
3&nbsp;&nbsp;&nbsp; 一个单一的，固定的流程语言。流程语言实际上是图形结构的集合，每个图形结构表示一个具体的，确定的运行时行为。在传统的引擎中，自然的只能支持一种流程语言，并且不可能加入新的图形结构。而使用流程虚拟机，流程的结构被作为可插入的。使用这个方法，它能够支持多种的流程语言，它也能作为实现有限的定制流程语言的基础，例如，在文档管理系统中。<br />
4&nbsp;&nbsp;&nbsp; 一个单一的环境。每个流程语言主要的对应它特别的环境。这个环境的具体可能是，比如，标准的java，企业级java，企业服务总线，或者jms队列，有或者没有持久化。许多流程语言，并且因此许多流程引擎，被设计成只能在某一种具体的环境中运行。我们承认不同的环境需要不同的流程语言，一种流程语言是不够的，但我们仍能实现一个流程虚拟机作为一个单一的基础，在这之上，其他的流程语言都能够被构成。<br />
5&nbsp;&nbsp;&nbsp; 与程序的逻辑绑定不容易。实际上，流程能够为现实生活中的业务流程提供很大的支持。但是，大部分情况是，它通常需要结合其他的技术，比如，你能够开发你的下一个工程而只使用java代码吗？没有xml配置文件？没有O/R映射？没有ant编译代码？自动的业务流程也如此：流程语言一定需要跟其他技术结合起来使用。一个工作流引擎需要使所有的结合融入java程序环境。这就是流程虚拟机确切的能够提供的。<br />
6&nbsp;&nbsp;&nbsp; 缺乏知识共享。今天的工作流市场是完全支离破碎的，每个引擎有它自己的流程语言概念和运行时概念。流程虚拟机的目的在于弥补这个鸿沟。每个程序员应该能在工作流，BPM和orchestration方面达成共识。<br />
软件开发的许多方面是基于图形的，长运行的执行。为了这些用例，流程虚拟机能作为一个基本的库来使用。通过使用这个库，我们能明显的减少建立流程语言的花费。它也能使定制流程语言变得更加切实可行。<br />
这篇文章实际上是各大领导开源社区达到共识的结果。这将使BPM,工作流和orchestration进入另一个层次。Red Hat(有JBoss jBPM)和Bull(Bonita,Orchestra)有多年的使用各种不同的流程语言和引擎的经验，以下的流程语言当前正在考虑形成一个单一的模型：JPDL,XPDL,BPEL,pageflow和线程流。<br />
流程虚拟机结合了有限状态机，petri网和其他工作流建模方法的最好的想法。<br />
<strong><font size="4"> 嵌入性</font></strong><br />
&nbsp;&nbsp;&nbsp; 当前的BPM，工作流和orchestration系统作为一个整体的引擎而建立，不能很好的与java软件的开发结合起来。可是，软件工程项目只有流程的技术的非常少。在多数情况，流程需要与其他的技术结合起来。而面对这种情况，运行时的流程引擎能否与java程序在各个层次上结合变得非常重要，在部署模型(把整个引擎当作一个库)，事务处理，在关系数据库中的持久化处理和用户界面的交互这些层面上。在所有的这些层面上，工作流引擎应该能自然的与应用程序结合起来。流程虚拟机已经证明能在标准的和企业级的java平台中提供这种嵌入式的功能。<br />
<strong><font size="4"> 可插拔特性</font></strong><br />
最重要的可插入点是结点的实现。流程结构的运行时行为使用java来实现。流程虚拟机将提供API来实现结点的行为。如果你从这个角度来看待它，流程虚拟机相当于一个建立流程结构的组件模型。<br />
为了让这个组件模型有效率，流程引擎使用的服务应该是可插拔的，例如：持久化，事务处理，身份组件，日志。为了弄清流程虚拟机如何能扩展来支持可插拔特性，请查阅流程虚拟机的全文。<br />
<strong><font size="4"> 另一边</font></strong><br />
流程引擎的市场现在完全是支离破碎的，不管是产品还是标准。至今为止的研究都是为了一种最好的流程语言。但是有这么多的不同的环境和不同的特点，一种流程语言将绝对不能满足要求。<br />
在java领域方面，流程虚拟机的方法都是独特的。但是在另一边，在microsoft的领域里，在windows的流程基础运行方法与在流程虚拟机中提议的非常相似。两者本质上都是组件模型。一个流程结构被看作一个组件，一个API和程序包都当作组件来提供，用来实现流程结构。<br />
&nbsp;&nbsp;&nbsp; 着两种技术有什么共同点，它们都把满足多个流程语言作为一个实现目标。因此它们都支持流程结构的组件模型，这意味着在这技术的基础上许多流程语言能被编译。这是一个流程引擎产品的全新的转换，不再去创建实现一个语言适用于多个应用环境的平衡的桥梁，这个问题反转过来了：用户被调整而来创建自己的流程语言。<br />
&nbsp;&nbsp;&nbsp; 一些流程语言可能是用于某个特定的目的。例如：jPDL使用在java环境中，BEPL使用在企业服务总线ESB环境中。但是有许多实现有限而简单的流程语言的机会&mdash;&mdash;例如，用来描述企业内容管理系统中流程审批的流程语言，用来描述多线程并发的流程语言，用来描述web应用系统页面流向的流程语言，等等。<br />
<strong><font size="4"> 基础</font></strong><br />
我想在具备了足够的背景资料之后，该是为了这块真实的肉而着手开始的时候了。以下这些是流程虚拟机的基本原则。整篇论文也将描述多个必须的扩展来应付多个可能的场景。<br />
流程是一个执行流程的图形化描述。例如，支票记录的过程就是一个流程。它能被部署在流程引擎中。一个流程可以有多个执行。例如，我上周一的支票记录应该被支票记录流程的一个具体执行来处理。图1显示了一个保险索赔的流程。<br />
图1：一个保险索赔的流程例子<br />
流程的基本结构是由结点和转换组成。转换有一个指引的方向，因此一个流程构成一个有向图。结点也能有一组嵌套结点。图2显示了在UML类图，转换和结点如何建模。&nbsp;<br />
图2：结点，转换以及他们的行为组成的类图<br />
流程中的每个结点都有相应的一块java代码与之相连，作为他们的行为。这是一个接口，与结点相关的java代码：<br />
public interface Executable {<br />
&nbsp; void execute(Execution execution) throws Exception;<br />
}<br />
现在，我们看这个执行。一个执行是一个指针，保持流程图的当前位置的轨迹。就象图3所示：&nbsp;<br />
图3：流程图当前位置的一个执行点<br />
当一个指定的流程的新的执行开始，初始时的结点将被指向这个流程的初始结点。之后，流程的这个执行将等待一个外部的触发。<br />
一个外部的触发将通过执行的方法process(String transitionName)来实现。这样的外部触发与有限状态机的信号操作非常相似。这个执行知道怎么样解释流程图。通过调用流程方法，执行将进入指定的(或默认的)转换，到达这个转换的目的结点。然后，执行将更新它的结点指针，并调用相应的结点行为。<br />
结点的行为通过执行有权访问当前的流程状态，执行被作为变量传递进来。这个相关更详细的描述在完整版的论文里面，实现了怎么样实现，例如，变量或者外部服务将通过执行来提供。<br />
在另一方面，结点的行为能够控制执行的传播。这意味着可执行的实现能运转，就象一个等待状态，继续执行，创建并发执行，或者更新执行中的任何信息。<br />
让我们来看看两个结点行为执行的例子。<br />
<strong><font size="4"> 1．&nbsp;&nbsp;&nbsp; 任务结点</font></strong><br />
为什么任务管理和工作流的关系如此紧密，是因为在软件系统中，人们的任务常常转化为等待状态。流程能使用以下的方式轻易的结合软件操作与人们的任务。<br />
流程执行引擎之外第一个需要的事情是任务的存储，任务需要为了人们的使用而有一个空间来保存。紧接着组成的是，一个用户接口，它允许人们看到他们的任务清单，然后完成它们。<br />
&nbsp;&nbsp;&nbsp; 然后你能设想以下的任务结点的执行行为。首先，一些外部触发必须被提供(使用流程的方法)以便流程能够开始执行，并且到达任务结点。任务行为的执行将为任务清单中指定的人们创建一个新的任务，任务也包含一个回退到相关的执行的操作。然后，结点行为在没有执行的传播时返回。这意味着当继续执行需要返回时执行将被指向任务结点。<br />
public class TaskNode implements Executable {<br />
&nbsp; String taskName;<br />
&nbsp; public void execute(Execution execution) {<br />
&nbsp;&nbsp;&nbsp; // find the responsible person for this new task<br />
&nbsp;&nbsp;&nbsp; User assignedUser = calculateUser(taskName, execution);<br />
&nbsp;&nbsp;&nbsp; // create the task <br />
&nbsp;&nbsp;&nbsp; Task task = new Task(taskName, assignedUser, execution);<br />
&nbsp;&nbsp;&nbsp; // add the task to the repository<br />
&nbsp;&nbsp;&nbsp; TaskRepository taskRepository = execution.getContext().getTaskRepository();<br />
&nbsp;&nbsp;&nbsp; taskRepository.addTask(task);<br />
&nbsp; }<br />
}<br />
&nbsp;&nbsp;&nbsp; 这个taskName成员变量显示在流程定义文件中详细指定的配置信息应该怎么样被注入到行为对象中。<br />
因此当系统正在等待用户完成任务时，执行能被持续保持。过一段时间后，当用户完成了任务，任务管理组件将使用相关的执行来提供一个触发。这个是用继续执行的方法完成的。然后执行将重新开始，离开任务结点，然后继续。<br />
<strong><font size="4"> 2．&nbsp;&nbsp;&nbsp; 决策结点</font></strong><br />
决策结点与任务结点不同在于它是自动的。一个条件需要评估并且基于评估结果；执行将立即被传播到一个离开转换。执行的传播是在决策结点的行为执行后，跟随执行方法的调用完成的，如下所示：<br />
public class DecisionNode implements Executable {<br />
&nbsp; Condition condition;<br />
&nbsp; public void execute(Execution execution) {<br />
&nbsp;&nbsp;&nbsp; // evaluate the condition<br />
&nbsp;&nbsp;&nbsp; String outcome = condition.evaluate(execution);<br />
&nbsp;&nbsp;&nbsp; <br />
&nbsp;&nbsp;&nbsp; // propagate the execution with the outcome of the condition<br />
&nbsp;&nbsp;&nbsp; execution.proceed(outcome);<br />
&nbsp; }<br />
}<br />
<strong><font size="4"> 执行的并发路径</font></strong><br />
整篇流程虚拟机论文描述对基本建模的表现以及之上的一系列扩展，例如，流程变量，动作，流程组合，异步执行，等等。但是最重要的扩展是合适的执行的并发路径。<br />
&nbsp;&nbsp;&nbsp; 在一些情况下，一个执行是不够的，为了保存当前执行的状态。例如，流程的开账单部分可能包含很多步骤，航运部分包含许多步骤，但是航运和开账单可以并行完成。因此，执行可以扩展成父子关系，这意味着一个执行能拥有很多子执行，每个子执行指向流程图中的它自己。<br />
<strong><font size="4"> 异步结构</font></strong><br />
&nbsp;&nbsp;&nbsp; 基本上，基于消息队列和web服务的体系结构总是异步的结构。异步的通讯意味着发送和接收方不共享同一个线程。接收消息与发送消息完全独立。<br />
&nbsp;&nbsp;&nbsp; Web服务时，一个web服务调用的结果总是同步的返回。但是当你希望对方调用你的web服务时返回你对对方的web服务调用时，就需要用到异步了。<br />
&nbsp;&nbsp;&nbsp; 现在我们来关心一个这样的软件系统的架构，许多系统使用异步的方式互相通信。当一个信息过来，系统必须回复，通过发送一个或多个信息到其他的系统。之后，这个系统可能希望相关的信息反馈。<br />
&nbsp;&nbsp;&nbsp; 一个流程可以表达这种一个单一系统中相关信息的全部的流程。<br />
<strong><font size="4"> 总结</font></strong><br />
&nbsp;&nbsp;&nbsp; 有多种流程语言，每个语言都有它自己的环境和目标使用案例。一些语言是通用目的的，一些语言是就比较局限，用来专门应用的。<br />
&nbsp;&nbsp;&nbsp; 流程虚拟机是一个简单但是强大的模型，它证明能支持各种工作流，BPM和orchestration语言。在这之上，它成为一个可插拔的，嵌入式设计的流程引擎。<br />
&nbsp;&nbsp;&nbsp; 当前的工作流技术仅仅是集中在业务分析。业务分析员与开发者的协作被严重的忽视了。流程虚拟机给了业务分析员更多的建模的自由。并且，它能使开发者平衡流程技术嵌入java应用程序。<br />
<strong><font size="4"> 资源</font></strong><br />
&middot;&nbsp;&nbsp;&nbsp; The full paper on The Process Virtual Machine <br />
&middot;&nbsp;&nbsp;&nbsp; JBoss jBPM <br />
&middot;&nbsp;&nbsp;&nbsp; Bonita The XPDL workflow engine by Bull hosted at OW2<br />
&middot;&nbsp;&nbsp;&nbsp; jPDL The workflow for Java process language of JBoss jBPM<br />
&middot;&nbsp;&nbsp;&nbsp; JBoss SEAM Pageflow The process language build on jBPM for specifying navigation between web pages<br />
&middot;&nbsp;&nbsp;&nbsp; Orchestra The BPEL engine from Bull hosted at OW2<br />
&middot;&nbsp;&nbsp;&nbsp; JBoss jBPM BPELThe BPEL engine from JBoss build on top of jBPM<br />
&middot;&nbsp;&nbsp;&nbsp; Windows Workflow Foundation <br />
&middot;&nbsp;&nbsp;&nbsp; XPDL The workflow language defined by the WfMC and supported by Bonita<br />
&middot;&nbsp;&nbsp;&nbsp; BPELThe service orchestration language defined by OASIS<br />
Tom Baeyens is the founder and lead developer of JBoss jBPM, an open source workflow, BPM and orchestration engine. He is an employee of Red Hat and participates in the Java Community Process.<br />
Miguel Valdes Faura is the Workflow Project Manager working for Bull R&amp;D. He is also member of the OW2 Technical Council in which he is leading the Bonita Workflow project.
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/85942#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Sat, 02 Jun 2007 20:01:00 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/85942</link>
        <guid>http://fly-ever.javaeye.com/blog/85942</guid>
      </item>
      <item>
        <title>servlet加载错误</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/75194" style="color:red;">http://fly-ever.javaeye.com/blog/75194</a>&nbsp;
          发表时间: 2007年04月26日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          错误：<br />
validateJarFile(C:\Program Files\Apache Software Foundation\Tomcat 5.0\webapps\EGovernment\WEB-INF\lib\javax.servlet.jar) - jar not loaded. See Servlet Spec 2.3, section 9.7.2. Offending class: javax/servlet/Servlet.class<br />
<br />
网上搜到的解决方案：<br />
<span style="font-size: 8pt; font-family: 宋体;"></span><span style="font-size: 8pt; font-family: 宋体;"><span style="color: red;"></span><span lang="EN-US" style="font-size: 8pt; color: red; font-family: Verdana;">tomcat </span><span style="font-size: 8pt; color: red; font-family: 宋体;">启动后先将</span><span lang="EN-US" style="font-size: 8pt; color: red; font-family: Verdana;">tomcat/common/lib</span><span style="font-size: 8pt; color: red; font-family: 宋体;">目录下的</span><span lang="EN-US" style="font-size: 8pt; color: red; font-family: Verdana;">jar</span><span style="font-size: 8pt; color: red; font-family: 宋体;">包全部读入内存，如果</span><span lang="EN-US" style="font-size: 8pt; color: red; font-family: Verdana;">webapps</span><span style="font-size: 8pt; color: red; font-family: 宋体;">目录里的应用程序中</span><span lang="EN-US" style="font-size: 8pt; color: red; font-family: Verdana;">WEB-INF/lib</span><span style="font-size: 8pt; color: red; font-family: 宋体;">目录下有相同的包，将无法加载</span><span style="font-size: 8pt; font-family: 宋体;">，估计不同版本的包之间也会造成类似问题。</span></span>
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/75194#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Thu, 26 Apr 2007 22:43:04 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/75194</link>
        <guid>http://fly-ever.javaeye.com/blog/75194</guid>
      </item>
      <item>
        <title>JBPM的流程定义</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/65901" style="color:red;">http://fly-ever.javaeye.com/blog/65901</a>&nbsp;
          发表时间: 2007年03月27日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <p class="MsoNormal" style=""><font size="3"><span lang="EN-US" style="font-size: 14pt; font-family: 宋体;">1</span><span style="font-size: 14pt; font-family: 宋体;">．<span lang="EN-US">JBPM</span>的版本：<st1:chsdate isrocdate="False" month="12" day="30" islunardate="False" w:st="on" year="1899"><span lang="EN-US">3.1.4</span></st1:chsdate><span lang="EN-US"><o:p></o:p></span></span></font></p>
<p class="MsoNormal" style=""><font size="3"><span lang="EN-US" style="font-size: 14pt; font-family: 宋体;">2</span></font><span style="font-size: 14pt; font-family: 宋体;"><font size="3">．<span lang="EN-US">JBPM</span>流程建模</font><span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US" style="font-family: 宋体;">JBPM</span><span style="font-family: 宋体;">的流程建模采用的是改良的<span lang="EN-US">UML</span>活动图，一是在用<span lang="EN-US">UML</span>活动图表述业务流程时，只建模状态层<span lang="EN-US">(</span>状态和控制流<span lang="EN-US">)</span>，不包括动作<span lang="EN-US">(UML</span>活动图没有区分状态和动作，它们都用活动来表示<span lang="EN-US">)</span>；二是如果多个迁移到达一个状态，缺省定义为不需要同步的合并<span lang="EN-US">(UML</span>活动图中默认是需要同步的联合<span lang="EN-US">)</span>。<span lang="EN-US">JBPM</span>定义了自己的流程定义语言<span lang="EN-US">JPDL</span>，用它来精确描述<span lang="EN-US">UML</span>活动图的每一个部分，采用的是<span lang="EN-US">XML</span>格式的。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span lang="EN-US" style="font-family: 宋体;">JBPM</span><span style="font-family: 宋体;">的流程建模结合应用了状态图，活动图和<span lang="EN-US">PetriNet</span>的知识，这里的活动图是<span lang="EN-US">UML2.0</span>版的。<span lang="EN-US">JBPM</span>使用的状态图的概念有<span lang="EN-US">transition/event</span>等； <span lang="EN-US">JBPM</span>的内部实现中还采用了<span lang="EN-US">PetriNet</span>的概念，如<span lang="EN-US">token,signal</span>等。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">&nbsp;&nbsp;&nbsp; 在<span lang="EN-US">UML</span>活动图没有区分状态和动作，在<span lang="EN-US">JBPM</span>中动作<span lang="EN-US">(actions)</span>就是一段程序逻辑，也就是工作流模型中的应用服务<sup><span lang="EN-US"></span></sup>。<span lang="EN-US"></span>在<span lang="EN-US">JBPM</span>中，状态<span lang="EN-US">(state)</span>这一术语与有限自动机<span lang="EN-US">(FSM)</span>或者<span lang="EN-US">UML</span>状态图中的<span lang="EN-US">state</span>具有相同的意义。状态是<span lang="EN-US">jBPM</span>的一个核心概念，也是业务流程的基本元素，状态代表了一种对外部参与者的依赖。定义状态时需要指定该状态的执行者，也就是该状态依赖的外部参与者。多个状态可能依赖同一个参与者，工作流管理系统根据这些信息构建该参与者的任务列表。<span lang="EN-US"><o:p></o:p></span>当开始在<span lang="EN-US">jBPM</span>中进行流程建模时，首先需要考虑业务流程的状态，状态将会成为你定义的流程的基本框架。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" style="text-indent: 21pt;"><font size="2"><span style="font-family: 宋体;">控制流包含一组状态和它们之间的关系。状态之间的逻辑关系描述了哪些执行路径可以同时执行，那些不可以。</span></font></p>
<p class="MsoNormal" style="text-indent: 21pt;"><span style="font-size: 9pt; font-family: 宋体;">可以用分叉<span lang="EN-US">(forks)</span>和联合<span lang="EN-US">(joins)</span>建模来表示流程中的分支路径，用判断<span lang="EN-US">(decisions)</span>来选择流程怎么样流向下一个节点。</span><span style="font-family: 宋体;"><font size="2"><span lang="EN-US"><o:p></o:p></span></font></span></p>
<p class="MsoNormal" style=""><font size="3"><span lang="EN-US" style="font-size: 14pt; font-family: 宋体;">3</span></font><span style="font-size: 14pt; font-family: 宋体;"><font size="3">．<span lang="EN-US">JBPM</span>的流程版本控制机制</font><span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;"><span style="">&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体;">一般情况下，流程定义不应该改变，因为预测流程变化带来的梭鱼可能的影响是非常困难的。<span lang="EN-US">JBPM</span>有一个明智的流程版本机制，版本机制允许在数据库中多个同名的流程定义共存，流程实例以当时最新的版本来启动，并且在它的整个生命周期中将保持以相同的流程定义执行。</span></p>
<p class="MsoNormal"><span lang="EN-US"><span style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>JBPM</span><span style="font-family: 宋体;">的版本控制机制可归结为以下几条原则：</span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;"><!--[if !supportLists]--><span lang="EN-US" style="font-family: 宋体;"><span style="">a)<span font-style:="" new="" font-stretch:="" font-size:="" line-height:="" font-weight:="" times="" font-size-adjust:="" roman="" font-variant:="" style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">当一个流程存档被部署时，将在</span><span lang="EN-US">jBPM</span><span style="font-family: 宋体;">数据库中创建一个新的流程定义。</span><span lang="EN-US" style="font-family: 宋体;"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;"><!--[if !supportLists]--><span lang="EN-US" style=""><span style="">b)<span font-style:="" new="" font-stretch:="" font-size:="" line-height:="" font-weight:="" times="" font-size-adjust:="" roman="" font-variant:="" style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">当一个被命名的流程定义被部署，部署器将分配一个版本号。为了分配版本号，部署器将查询同名流程定义的最高版本号，并且在其上加</span><span lang="EN-US">1</span><span style="font-family: 宋体; color: red;">.</span><span style="font-family: 宋体; color: red;"></span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;"><!--[if !supportLists]--><span lang="EN-US" style="font-family: 宋体;"><span style="">c)<span font-style:="" new="" font-stretch:="" font-size:="" line-height:="" font-weight:="" times="" font-size-adjust:="" roman="" font-variant:="" style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><!--[endif]--><span style="font-family: 宋体;">当一个新的版本被部署，新的流程实例以新版本启动，而老的流程实例则以老的流程定义继续执行，直到它结束为止。</span><span lang="EN-US" style="font-family: 宋体;"><o:p></o:p></span></p>
<p class="MsoNormal" style="margin-left: 21pt; text-indent: -21pt;"><!--[if !supportLists]--><span lang="EN-US" style="font-family: 宋体;"><span style="">d)<span font-style:="" new="" font-stretch:="" font-size:="" line-height:="" font-weight:="" times="" font-size-adjust:="" roman="" font-variant:="" style="">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span><!--[endif]--><span lang="EN-US">JBPM</span><span style="font-family: 宋体;">甚至能够对与一个流程相关的程序逻辑进行版本控制，通过在流程存档中包括</span><span lang="EN-US">java</span><span style="font-family: 宋体;">类，</span><span lang="EN-US">JBPM</span><span style="font-family: 宋体;">能够将每个流程定义的类分离。</span><span lang="EN-US" style="font-family: 宋体;"><o:p></o:p></span></p>
<p class="MsoNormal" style=""><font size="3"><span lang="EN-US" style="font-size: 14pt; font-family: 宋体;">4</span></font><span style="font-size: 14pt; font-family: 宋体;"><font size="3">．<span lang="EN-US">JPDL</span>具体分析</font><span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; text-indent: 21pt;"><span style="font-family: 宋体;">为了把复杂的企业经营过程定义成工作流引擎可以理解的形式化信息及工作流管理系统可以管理的工作流</span><span lang="EN-US" style="font-family: 宋体;">,</span><span style="font-family: 宋体;">需要建立计算机化的工作流模型。为了全面描述经营过程</span><span lang="EN-US" style="font-family: 宋体;">,</span><span style="font-family: 宋体;">工作流模型通常又包含三个子模型</span><span lang="EN-US" style="font-family: 宋体;">,</span><span style="font-family: 宋体;">分别是过程模型</span><span lang="EN-US" style="font-family: 宋体;">,</span><span style="font-family: 宋体;">资源模型和组织模型。过程模型描述经营过程中的活动以及活动之间的关系</span><span lang="EN-US" style="font-family: 宋体;">,</span><span style="font-family: 宋体;">资源模型描述活动所需要的软硬件资源</span><span lang="EN-US" style="font-family: 宋体;">,</span><span style="font-family: 宋体;">而组织模型描述活动的执行实体。过程模型是工作流模型的核心</span><span lang="EN-US" style="font-family: 宋体;">,</span><span style="font-family: 宋体;">比较常见的过程建模方法有</span><span lang="EN-US" style="font-family: 宋体;">Petri</span><span style="font-family: 宋体;">网、活动图、状态图等。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; text-indent: 21pt;"><span style="font-family: 宋体;">针对具体的<span lang="EN-US">JBPM</span>的流程建模，</span><span style="font-family: 宋体;">具体的在<span lang="EN-US">JBPM</span>中，一个业务流程是用<span lang="EN-US">xml</span>文件的形式表现出来的，其包含的元素如下：<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span style="font-family: 宋体;">一个业务流程的定义<span lang="EN-US">process-definition</span>，有一个流程定义名称，其流程内容主要由下面七个部分组成：<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">1</span><span style="font-family: 宋体;">，<span lang="EN-US">swimlane</span>，泳道，它们被用于任务分配</span><sup><span lang="EN-US" style="font-size: 12pt; font-family: 宋体;"></span></sup><span style="font-family: 宋体;">，一个泳道可以被视为一个参与者在这一流程中的角色名称。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">2</span><span style="font-family: 宋体;">，<span lang="EN-US">start-state</span>，流程的起始状态，所有的流程实例都是从这个状态开始的，没有起始状态的流程是合法的，但不能被执行；<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">3</span><span style="font-family: 宋体;">，<span lang="EN-US">node-elements</span>，包含一系统流程定义的节点，这些节点类型包括<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">end-state|state|node|task-node|process-state|super-state|fork|join|decision<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;"><span style="">&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体;">没有流程定义的流程是合法的，但不能被执行；<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">4</span><span style="font-family: 宋体;">，<span lang="EN-US">action-elements</span>，全局定义的动作，可以在事件和转换中引用，为了被引用，这些动作必须被指定名称；包括<span lang="EN-US"> action|script|create-timer|cancel-timer<o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">5</span><span style="font-family: 宋体;">，<span lang="EN-US">event</span>，事件，服务于动作的流程事件；<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">6</span><span style="font-family: 宋体;">，<span lang="EN-US">task</span>，全局定义的任务，可以在动作中使用；<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal"><span lang="EN-US" style="font-family: 宋体;">7</span><span style="font-family: 宋体;">，<span lang="EN-US">exception-handler</span>，一个异常处理器列表，用于这个流程定义中的委托类所抛出的所有异常。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="text-align: left;"><span lang="EN-US" style="font-family: 宋体;"><span style="">&nbsp;&nbsp;&nbsp; </span></span><span style="font-family: 宋体;">在<span lang="EN-US">JPDL</span>包含的这些元素中，<span lang="EN-US">node-elements</span>中定义的为一系统的包含各种类型的</span><span lang="EN-US" style="font-family: 宋体;">node-elements</span><span style="font-family: 宋体;">，这些</span><span lang="EN-US" style="font-family: 宋体;">node-elements</span><span style="font-family: 宋体;">描述了整个流程包含的各个状态，以及状态之间的转换。即相当于流程的过程模型。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; text-indent: 21pt;"><span style="font-family: 宋体;">而在这些</span><span lang="EN-US" style="font-family: 宋体;">node-elements</span><span style="font-family: 宋体;">的状态转换时，可以调用相应的<span lang="EN-US">action-elements</span>，</span><span lang="EN-US" style="font-family: 宋体;">node-elements</span><span style="font-family: 宋体;">也有支持的<span lang="EN-US">event</span>类型，所以能够调用相应的<span lang="EN-US">event</span>，在<span lang="EN-US">event</span>中，也可以调用相应的<span lang="EN-US">action-elements</span>。而<span lang="EN-US">action</span>是指实现用户指定的行为，通过实现<span lang="EN-US">org.jbpm.graph.def.ActionHandler</span>接口来实现。所以可以在流程中，得到用户的或者其他应用程序的资源。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; text-indent: 21pt;"><span style="font-family: 宋体;">当</span><span lang="EN-US" style="font-family: 宋体;">node-element</span><span style="font-family: 宋体;">为<span lang="EN-US">task-node</span>时，即流程包含的任务，可以为这些任务指定任务的执行者，通过<span lang="EN-US">swimlane</span>属性直接指定或者通过<span lang="EN-US">assignment</span>来实现一个委托，即实现一个<span lang="EN-US">org.jbpm.taskmgmt.def.AssignmentHandler</span>接口来分派任务执行者。<span lang="EN-US"><o:p></o:p></span></span></p>
<p class="MsoNormal" align="left" style="text-align: left; text-indent: 21pt;"><span style="font-family: 宋体;">因此使用<span lang="EN-US">JPDL</span>，可以从过程模型，资源模型，组织模型来完整的描述一个业务流程。<span lang="EN-US"><o:p></o:p></span></span></p>
<div style=""><!--[if !supportFootnotes]--><br clear="all" />
<hr size="1" align="left" width="33%" />
<!--[endif]-->
<div id="ftn1" style="">
<p class="MsoFootnoteText"><a href="#_ftnref1" name="_ftn1" title="" style=""><span class="MsoFootnoteReference"><span lang="EN-US"><span style=""><!--[if !supportFootnotes]--><span class="MsoFootnoteReference"><span new="" times="" lang="EN-US" roman="" style="font-size: 9pt;"></span></span></span></span></span></a><span style="font-family: 宋体;">参考《</span><span lang="EN-US">JBPM3.1</span><span style="font-family: 宋体;">用户指南》</span><span style="font-family: 宋体;"></span></p>
</div>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/65901#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 27 Mar 2007 22:42:21 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/65901</link>
        <guid>http://fly-ever.javaeye.com/blog/65901</guid>
      </item>
      <item>
        <title>JBPM的流程定义插件</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/59283" style="color:red;">http://fly-ever.javaeye.com/blog/59283</a>&nbsp;
          发表时间: 2007年03月12日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          这段时间，把jbpm-starters-kit-3.1.4包下下来了，想好好的研究一下。<br />
今天把JBPM的流程设计器插件放到eclipse环境中，终于可以在eclipse环境中可视化的操作流程定义了。<br />
一开始以为把流程设计器插件放如eclipse环境中蛮复杂，所以也看了网上的一些步骤，可越看感觉越麻烦。干脆没动手了。<br />
想到每次在eclipse中装插件的方法，今天就想试一下，我用的是myeclipse，于是把jbpm-starters-kit-3.1.4\jbpm-designer\jbpm-gpd-feature\eclipse下的features和plugins分别放入myeclipse的对应文件夹中，结果发现可以了，呵呵。<br />
这个插件只支持eclipse 3.1以上的一些版本。
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/59283#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 12 Mar 2007 15:47:09 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/59283</link>
        <guid>http://fly-ever.javaeye.com/blog/59283</guid>
      </item>
      <item>
        <title>Java参数传递机制</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/49204" style="color:red;">http://fly-ever.javaeye.com/blog/49204</a>&nbsp;
          发表时间: 2007年01月22日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <font color="#ff00ff"><br />
来自：http://blog.sina.com.cn/u/55f67d23010003dz<br />
<br />
Java参数，不管是原始类型还是引用类型，传递的都是副本(有另外一种说法是传值，但是说传副本更好理解吧，传值通常是相对传址而言)。</font>
<div><font color="#ff00ff">&nbsp;&nbsp;&nbsp; 如果参数类型是原始类型，那么传过来的就是这个参数的一个副本，也就是这个原始参数的值，这个跟之前所谈的传值是一样的。</font></div>
<div><font color="#ff00ff">&nbsp;&nbsp;&nbsp; 如果参数类型是引用类型，那么传过来的就是这个引用参数的副本，这个副本存放的是参数的地址。如果在函数中没有改变这个副本的地址，而是改变了地址中的 值，那么在函数内的改变会影响到传入的参数。如果在函数中改变了副本的地址，如new一个，那么副本就指向了一个新的地址，此时传入的参数还是指向原来的 地址，所以不会改变参数的值。</font></div>
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/49204#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 22 Jan 2007 19:21:03 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/49204</link>
        <guid>http://fly-ever.javaeye.com/blog/49204</guid>
      </item>
      <item>
        <title>java中的变量初始化问题</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/44430" style="color:red;">http://fly-ever.javaeye.com/blog/44430</a>&nbsp;
          发表时间: 2007年01月08日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在学习java时，知道java中的变量需要初始化之后才能够使用，否则会报错，所以我当时一直迷惑什么时候才能够用到java基本类型中的一些默认初始值，因为我在编程过程中，总是先为变量赋初值之后才使用的。<br />
今天看到了一个使用java基本类型的默认值的例子，所以拿出来看一下：
<div class="code_title">java 代码</div>
<div class="dp-highlighter">
<div class="bar">&nbsp;</div>
<ol class="dp-j" start="1">
    <li class="alt"><span><span class="keyword">class</span><span>&nbsp;subTest&nbsp;{&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">int</span><span>&nbsp;a;&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;&nbsp;subTest(</span><span class="keyword">int</span><span>&nbsp;v){&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;a+=v;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;System.out.println(a&nbsp;+&nbsp;<span class="string">&quot;&quot;</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;</span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">public</span><span>&nbsp;</span><span class="keyword">static</span><span>&nbsp;</span><span class="keyword">void</span><span>&nbsp;main(String&nbsp;args[]){&nbsp;&nbsp;&nbsp;</span></span></li>
    <li class=""><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<span class="keyword">new</span><span>&nbsp;subTest(</span><span class="number">1</span><span>);&nbsp;&nbsp;</span></span></li>
    <li class="alt"><span>&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span></li>
    <li class=""><span>}&nbsp;&nbsp;</span></li>
</ol>
</div>
<br />
当我看这个例子时，以为这个程序不会通过编译，结果它却正确的执行了。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后来我仔细的考虑了一下，估计应该是该变量a是在构造方法中使用的，而构造方法本来就是用来初始化的，所以在这里能够正确运行，并且a使用的是它的默认值0。<br />
&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不知道有谁想过这个问题没有，大家都是怎么解释的呢？
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/44430#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Mon, 08 Jan 2007 17:39:29 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/44430</link>
        <guid>http://fly-ever.javaeye.com/blog/44430</guid>
      </item>
      <item>
        <title>对象的串行化</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/35374" style="color:red;">http://fly-ever.javaeye.com/blog/35374</a>&nbsp;
          发表时间: 2006年11月21日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          <div class="entity">
<h2 class="diaryTitle">转载自http://gardenlee.bokee.com/2049297.html</h2>
<h2 class="diaryTitle">对象的串行化（Serialization）和transient关键字- -</h2>
<p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 				 </p>
<p>对象的串行化（<font face="Arial">Serialization</font>） 一、串行化的概念和目的 </p>
<p class="MsoNormal"><strong>1.</strong><strong>什么是串行化</strong></p>
<p class="MsoNormal" style="text-indent: 18pt;">对 象的寿命通常随着生成该对象的程序的终止而终止。有时候，可能需要将对象的状态保存下来，在需要时再将对象恢复。我们把对象的这种能记录自己的状态以便将 来再生的能力。叫作对象的持续性(persistence)。对象通过写出描述自己状态的数值来记录自己 ，这个过程叫对象的串行化(Serialization) 。串行化的主要任务是写出对象实例变量的数值。如果交量是另一对象的引用，则引用的对象也要串行化。这个过程是递归的，串行化可能要涉及一个复杂树结构的 单行化，包括原有对象、对象的对象、对象的对象的对象等等。对象所有权的层次结构称为图表(graph)。</p>
<p class="MsoNormal"><strong>2.</strong><strong>串行化的目的</strong></p>
<p class="MsoNormal">Java对象的单行化的目标是为Java的运行环境提供一组特性，如下所示：</p>
<p class="MsoNormal" style="text-indent: -21pt;">1)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 尽量保持对象串行化的简单扼要 ，但要提供一种途径使其可根据开发者的要求进行扩展或定制。</p>
<p class="MsoNormal" style="text-indent: -21pt;">2)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 串行化机制应严格遵守Java的对象模型 。对象的串行化状态中应该存有所有的关于种类的安全特性的信息。</p>
<p class="MsoNormal" style="text-indent: -21pt;">3)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对象的串行化机制应支持Java的对象持续性。</p>
<p class="MsoNormal" style="text-indent: -21pt;">4)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对象的串行化机制应有足够的 可扩展能力以支持对象的远程方法调用(RMI)。</p>
<p class="MsoNormal" style="text-indent: -21pt;">5)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 对象串行化应允许对象定义自身 的格式即其自身的数据流表示形式，可外部化接口来完成这项功能。</p>
二、串行化方法
<p class="MsoNormal" style="text-indent: 18pt;">从JDK1.1开始，Java语言提供了对象串行化机制 ，在java.io包中，接口Serialization用来作为实现对象串行化的工具 ，只有实现了Serialization的类的对象才可以被串行化。</p>
<p class="MsoNormal" style="text-indent: 18pt;">Serializable接口中没有任何的方法。当一个类声明要实现Serializable接口时，只是表明该类参加串行化协议，而不需要实现任何特殊的方法。下面我们通过实例介绍如何对对象进行串行化。</p>
<p class="MsoNormal"><strong>1.</strong><strong>定义一个可串行化对象</strong></p>
<p class="MsoNormal" style="text-indent: 10pt;">一个类，如果要使其对象可以被串行化，必须实现Serializable接口。我们定义一个类Student如下：</p>
<p class="MsoNormal"><strong>　　</strong><strong>public class Student implements Serializable{</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>int id</strong><strong>；</strong><strong> //</strong><strong>学号</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>String name</strong><strong>；</strong><strong> //</strong><strong>姓名</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>int age</strong><strong>；</strong><strong> //</strong><strong>年龄</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>String department //</strong><strong>系别</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>public Student(int id,String name,int age, String depart</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>ment){</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>this.id=id</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>this.name=name</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>this.age=age</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>this.department=department</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>}</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>}</strong></p>
<p class="MsoNormal"><strong>2.</strong><strong>构造对象的输入／输出流</strong></p>
<p class="MsoNormal" style="text-indent: 22.7pt;">要串行化一个对象，必须与一定的对象输出／输入流联系起来，通过对象输出流将对象状态保存下来，再通过对象输入流将对象状态恢复。</p>
<p class="MsoNormal" style="text-indent: 22.7pt;">java.io 包中，提供了ObjectInputStream和ObjectOutputStream将数据流功能扩展至可读写对象 。在ObjectInputStream 中用readObject()方法可以直接读取一个对象，ObjectOutputStream中用writeObject()方法可以直接将对象保存到 输出流中。</p>
<p class="MsoNormal" style="text-indent: 10pt;">&nbsp;</p>
<p class="MsoNormal"><strong>　　</strong><strong>public class ObjectSer{</strong></p>
<p class="MsoNormal"><strong>　　　</strong><strong>public static void main(String args[ ])throws IOExcep</strong></p>
<p class="MsoNormal"><strong>　　　</strong><strong>tion,ClassNotFoundException{</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>Student stu=new Student(981036,&rdquo;LiuMing&rdquo;,18,&rdquo;CSD&rdquo;)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>FileOutputStream fo=new FileOutputStream(&rdquo;data.ser&rdquo;)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>ObjectOutputStream so=new ObjectOutputStream(fo)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>try{</strong></p>
<p class="MsoNormal"><strong>　　　　</strong><strong>so.writeObject(stu)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　　　</strong><strong>so.close()</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>}catch(IOExcption)</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>{ System.out.println(e)</strong><strong>；</strong><strong>}</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>stu=null</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>FileInputStream fi=new FileInputStream(&ldquo;data.ser&rdquo;)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>ObjetctInputStream si=new ObjectInputStream(fi)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>try{</strong></p>
<p class="MsoNormal"><strong>　　　　</strong><strong>stu=(Student)si.readObject</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　　　</strong><strong>si.close()</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>}catch(IOException)</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>{System.out.println(e)</strong><strong>；</strong><strong>}</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>System.out.println(&ldquo;Student Info:&rdquo;)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>System.out.println(&ldquo;ID:&rdquo;+stu.id)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>System.out.println(&ldquo;Name:&rdquo;+stu.name)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>System.out.println(&ldquo;Age:&rdquo;+stu.age)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>System.out.println(&ldquo;Dep:&rdquo;+stu.department)</strong><strong>；</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>}</strong></p>
<p class="MsoNormal"><strong>　　</strong><strong>}</strong></p>
<div style="border: 1pt solid windowtext; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;">
<p class="MsoNormal" style="border: medium none ; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>　　运行结果如下：</strong></p>
<p class="MsoNormal" style="border: medium none ; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>&nbsp;</strong></p>
<p class="MsoNormal" style="border: medium none ; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>　　</strong><strong>Student Info:</strong></p>
<p class="MsoNormal" style="border: medium none ; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>　　</strong><strong>ID:981036</strong></p>
<p class="MsoNormal" style="border: medium none ; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>　　</strong><strong>Name:LiuMing</strong></p>
<p class="MsoNormal" style="border: medium none ; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>　　</strong><strong>Age:18</strong></p>
<p class="MsoNormal" style="border: medium none ; background: rgb(217, 217, 217) none repeat scroll 0% 50%; -moz-background-clip: -moz-initial; -moz-background-origin: -moz-initial; -moz-background-inline-policy: -moz-initial;"><strong>　　</strong><strong>Dep:CSD</strong></p>
</div>
<p class="MsoNormal" style="text-indent: 10pt;">&nbsp;</p>
<p class="MsoNormal" style="text-indent: 10pt;">在这个例子中，我们首先定义了一个类Student，实现了Seriali</p>
<p class="MsoNormal" style="text-indent: 10pt;">zable 接口 ，然后通过对象输出流的writeObject()方法将Student对象保存到文件 data.ser中 。之后，通过对家输入流的readObjcet()方法从文件data.ser中读出保存下来的Student对象 。从运行结果可以看到，通过串行化机制，可以正确地保存和恢复对象的状态。</p>
三、串行化的注意事项
<p class="MsoNormal"><strong>1.</strong><strong>串行化能保存的元素</strong></p>
<p class="MsoNormal" style="text-indent: 10pt;">串行化只能保存对象的非静态成员交量，不能保存任何的成员方法和静态的成员变量，而且串行化保存的只是变量的值，对于变量的任何修饰符都不能保存。</p>
<p class="MsoNormal"><strong>2.transient</strong><strong>关键字</strong></p>
<p class="MsoNormal" style="text-indent: 10pt;">对于某些类型的对象，其状态是瞬时的，这样的对象是无法保存其状态的。例如一个Thread对象或一个FileInputStream对象 ，对于这些字段，我们必须用transient关键字标明，否则编译器将报措。</p>
<p class="MsoNormal" style="text-indent: 10pt;">另 外 ，串行化可能涉及将对象存放到 磁盘上或在网络上发达数据，这时候就会产生安全问题。因为数据位于Java运行环境之外，不在Java安全机制的控制之中。对于这些需要保密的字段，不应 保存在永久介质中 ，或者不应简单地不加处理地保存下来 ，为了保证安全性。应该在这些字段前加上transient关键字。 </p>
<p class="diaryFoot">- 作者： <a href="javascript:void(0);" onclick="window.open('http://publishblog.blogchina.com/blog/postMessage.b?receiver=182020','发送短消息','width=520, height=455')">gardenlee</a> 访问统计： <script language="JavaScript" src="http://counter.blogchina.com/PageServlet?pageid=2049297&blogid=180512" type="text/javascript"></script> 290　2005年06月24日, 星期五 14:56                <a href="javascript:void(keyit=window.open('http://blogmark.blogchina.com/jsp/key/quickaddkey.jsp?k='+encodeURI('%E5%AF%B9%E8%B1%A1%E7%9A%84%E4%B8%B2%E8%A1%8C%E5%8C%96%EF%BC%88Serialization%EF%BC%89%E5%92%8Ctransient%E5%85%B3%E9%94%AE%E5%AD%97')+'&amp;u='+encodeURI('http://gardenlee.blogchina.com/gardenlee/2049297.html')+'&amp;c='+encodeURI(''),'keyit','scrollbars=no,width=500,height=430,status=no,resizable=yes'));keyit.focus();">加入博采</a>              </p>
</div>
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/35374#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Tue, 21 Nov 2006 16:53:32 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/35374</link>
        <guid>http://fly-ever.javaeye.com/blog/35374</guid>
      </item>
      <item>
        <title>(转)每个团队都应该有一个Appfuse式的项目</title>
        <author>fly_ever</author>
        <description>
          <![CDATA[
          <br/>
          作者: <a href="http://fly-ever.javaeye.com">fly_ever</a>&nbsp;
          链接：<a href="http://fly-ever.javaeye.com/blog/27040" style="color:red;">http://fly-ever.javaeye.com/blog/27040</a>&nbsp;
          发表时间: 2006年10月11日
          <br/><br/>
          声明：本文系JavaEye网站发布的原创博客文章，未经作者书面许可，严禁任何网站转载本文，否则必将追究法律责任！
          <br/><br/>
          引文地址：http://www.blogjava.net/calvin/archive/2005/09/13/12878.html<br />每个团队都应该有一个Appfuse式的项目<br />    作者：江南白衣 <br /><br />    一个Appfuse式的项目，会通过项目里最典型的几个场景，demo团队目前的体系框架和设计模式。 <br /><br />   它的好处有一打，比如为所有项目提供共同的Library Stack，提供最可靠的代码蓝本，保证大家的模式和代码风格一致，加快知识在团队的传播，方便新人的融入，还有为试验代码提供一个稳定简洁的环境。<br /><br />   所以，一个长期合作的团队，需要这样一个MyAppfuse。<br /><br />   但还要有三条铁的纪律，才能保证辛苦做出来的MyAppFuse不是个寂寞的芭比。<br />   一是强制更新，所有团队approval的最新模式都要refactor到MyAppfuse中。<br />   二是规范更新，每次更新都要严格测试并编写更新记录、移植文档。<br />   三是强制Copy Start，所有代码都必须从MyAppFuse里Copy而不是随自己喜欢找任意项目的代码。<br /><br />   现在开始规划一个Appfuse式项目。我觉得包含如下Content：<br />   1.设计典型的应用情景。<br />       我平时的ERP项目，最典型的情景莫过于：<br />       *基础资料管理（如产品资料的CRUD)<br />       *单据管理（如订单的录入与管理）<br />       *典型报表<br /><br />       每个场景应该有简单与复杂两种模式，方便Developer选用。<br />       场景要仔细设计，尽量演示到所有重要的技术要点。<br />       但场景又要尽量的少，尽量简洁，减少每次模式升级的成本。<br /><br />   2.挑选出其他比较重要的特性。<br />        如Quartz、ClickStream，也一并放入MyAppFuse中。<br /><br />   3.把所有用到的框架、类库、瓶瓶罐罐统统打包。<br />       并附上索引和说明作为团队公用的Library Stack，每次library升级都要认真检测。<br /><br />   4.编写文档。<br />        类似Appfuse的Tutorial，编写文档说明各个场景用到的技术要点与模式，说明如何二次开发。<br />        类似Appfuse的Migrate，详细说明如何升级到MyAppfuse新的版本，促进新模式的传播。<br /><br />   5.简单代码生成工具。<br />       类似Appfuse的AppGen，用Groovy Template或FreeMarker编写简单的代码生成模版。<br /><br />   6.核心的测试用例<br /><br />    后记:这个MyAppfuse终于开源成http://www.springside.org.cn
          <br/>
          <span style="color:red;">
            <a href="http://fly-ever.javaeye.com/blog/27040#comments" style="color:red;">本文的讨论也很精彩，浏览讨论>></a>
          </span>
          <br/><br/><br/>
          <span style="color:#E28822;">JavaEye推荐</span>
          <br/>
          <ul class='adverts'><li><a href='/adverts/106' target='_blank'><span style="color:blue;font-weight:bold;">JavaEye问答大赛开始了！ 从6月23日 至 7月6日，奖品丰厚 ！</span></a></li><li><a href='/adverts/42' target='_blank'><span style="color:red;font-weight:bold;">搜狐网站诚聘Java、PHP和C++工程师</span></a></li><li><a href='/adverts/97' target='_blank'><span style="color:blue;font-weight:bold;">Oracle专区上线，有Oracle最新文章，重要下载及知识库等精彩内容，欢迎访问。</span></a></li><li><a href='/adverts/41' target='_blank'><span style="color:red;font-weight:bold;">北京: 千橡集团暨校内网诚聘软件研发工程师</span></a></li><li><a href='/adverts/92' target='_blank'><span style="color:red;font-weight:bold;">快来参加7月17日在成都举行的SOA中国技术论坛</span></a></li></ul>
          <br/><br/><br/>
          ]]>
        </description>
        <pubDate>Wed, 11 Oct 2006 15:14:41 +0800</pubDate>
        <link>http://fly-ever.javaeye.com/blog/27040</link>
        <guid>http://fly-ever.javaeye.com/blog/27040</guid>
      </item>
  </channel>
</rss>