1.在JSP文件中加上:
<%@ page contentType="text/html; charset=utf-8" %>
<html:html lang="true"></html:html>
2.使用以下形式輸出字符:
<bean:message bundle="index" key="Anonymous"/>
3.建立類似以下形式的文件(放在classses目錄下):
application_en_US.properties
application_zh_TW.properties
application_zh_CN.properties
其中可能用到這樣的命令:
native2ascii application_cn.properties application_zh_CN.properties
posted @
2006-06-07 14:44 崛起的程序員 閱讀(248) |
評論 (0) |
編輯 收藏
以下所說的struts-config.xml和ApplicationResources.properties等文件名是缺省時使用的,如果你使用了多模塊,或指定了不同的資源文件名稱,這些名字要做相應的修改。
1、“No bean found under attribute key XXX”
在struts-config.xml里定義了一個ActionForm,但type屬性指定的類不存在,type屬性的值應該是Form類的全名。或者是,在Action的定義中,name或attribute屬性指定的ActionForm不存在。
2、“Cannot find bean XXX in any scope”
在Action里一般會request.setAttribute()一些對象,然后在轉向的jsp文件里(用tag或request.getAttribute()方法)得到這些對象并顯示出來。這個異常是說jsp要得到一個對象,但前面的Action里并沒有將對象設置到request(也可以是session、servletContext)里。
可能是名字錯了,請檢查jsp里的tag的一般是name屬性,或getAttribute()方法的參數值;或者是Action邏輯有問題沒有執行setAttribute()方法就先轉向了。
還有另外一個可能,純粹是jsp文件的問題,例如<logic:iterate>會指定一個id值,然后在循環里<bean:write>使用這個值作為name的值,如果這兩個值不同,也會出現此異常。(都是一個道理,request里沒有對應的對象。)
3、“Missing message for key "XXX"”
缺少所需的資源,檢查ApplicationResources.properties文件里是否有jsp文件里需要的資源,例如:
<bean:message key="msg.name.prompt"/>
這行代碼會找msg.name.prompt資源,如果AppliationResources.properties里沒有這個資源就會出現本異常。在使用多模塊時,要注意在模塊的struts-config-xxx.xml里指定要使用的資源文件名稱,否則當然什么資源也找不到,這也是一個很容易犯的錯誤。
4、“No getter method for property XXX of bean teacher”
這條異常信息說得很明白,jsp里要取一個bean的屬性出來,但這個bean并沒有這個屬性。你應該檢查jsp中某個標簽的property屬性的值。例如下面代碼中的cade應該改為code才對:
<bean:write name="teacher" property="cade" filter="true"/>
5、“Cannot find ActionMappings or ActionFormBeans collection”
待解決。
6、“Cannot retrieve mapping for action XXX”
在.jsp的<form>標簽里指定action='/XXX',但這個Action并未在struts-config.xml里設置過。
7、HTTP Status 404 - /xxx/xxx.jsp
Forward的path屬性指向的jsp頁面不存在,請檢查路徑和模塊,對于同一模塊中的Action轉向,path中不應包含模塊名;模塊間轉向,記住使用contextRelative="true"。
8、沒有任何異常信息,顯示空白頁面
可能是Action里使用的forward與struts-config.xml里定義的forward名稱不匹配。
9、“The element type "XXX" must be terminated by the matching end-tag "XXX".”
這個是struts-config.xml文件的格式錯誤,仔細檢查它是否是良構的xml文件,關于xml文件的格式這里就不贅述了。
10、“Servlet.init() for servlet action threw exception”
一般出現這種異常在后面會顯示一個關于ActionServlet的異常堆棧信息,其中指出了異常具體出現在代碼的哪一行。我曾經遇到的一次提示如下:
java.lang.NullPointerException
??? at org.apache.struts.action.ActionServlet.parseModuleConfigFile(ActionServlet.java:1003)
??? at org.apache.struts.action.ActionServlet.initModuleConfig(ActionServlet.java:955)
為解決問題,先下載struts的源碼包,然后在ActionServlet.java的第1003行插入斷點,并對各變量進行監視。很丟人,我竟然把struts-config.xml文件弄丟了,因此出現了上面的異常,應該是和CVS同步時不小心刪除的。
11、“Resources not defined for Validator”
這個是利用Validator插件做驗證時可能出現的異常,這時你要檢查validation.xml文件,看里面使用的資源是否確實有定義,form的名稱是否正確,等等。
posted @
2006-06-07 14:43 崛起的程序員 閱讀(248) |
評論 (0) |
編輯 收藏
這只小貓玩了它差不多也有一年多了,還沒仔細瞅瞅長個什么樣。當它耍性子的時候,常常弄的我手足無措,因為不懂它說出的一大堆亂七八糟的洋話。為了能讓它說start就start,說down就down,下面要開始一段我訓獸師的經歷 ^_^。
寵物簡介
Jakarta Tomcat服務器是一種Servlet/JSP容器,經歷了3.x到4.0.x到4.1.x的變遷,現在最新的版本為5.0.x,支持Servlet2.4和JSP2.0規范,從apache網站上下載Tomcat 5,在環境變量中配置一下JAVA_HOME,小貓就能生靈活現的跑起來了。若小貓啟動失敗,DOS窗口會自動關閉,若運行catalina run命令DOS窗口是不會自動關閉的。
tomcat中有三個放置java庫的地方,分別是/server/lib、/shared/lib和/common/lib。
區別:/server/lib - 其中的jar文件只能被tomcat服務器訪問。
/shared/lib - 其中的jar文件可以被所有的Web應用訪問,但不能被tomcat服務器訪問到。
/common/lib - Web服務和tomcat服務器都可以訪問的到。
server.xml文件解析 - 文件位置是<%CATALINA_HOME%>/conf/server.xml
配置虛擬主機
Host元素代表虛擬主機,在同一個Engine元素下可以配置多個虛擬主機。打開server.xml文件可以發現Engine元素下已經有一個名為localhost的Host元素了,可以在它后面加入下列代碼:
<
Host?
name
="www.myname.com"
?debug
="0"
?appBase
="c:\myname"
?unpackWar
="true"
?autoDeploy
="true"
>
??? <
alias
>
www.myname1.com
</
alias
>
??? <
alias
>
www.myname2.com
</
alias
>
??? <
Context?
pathh
="/helloapp"
?docBase
="helloapp"
?debug
="0"
?reloadable
="true"
/>
</
Host
>
?
Session的使用
Session是一種用來跟蹤用戶狀態的機制,那它是怎么實現的呢?Servlet容器通過在客戶端瀏覽器中保存一個Session ID來跟蹤Session,調用session.getID()可以看到你的Session ID是多少。如果客戶端支持Cookie,就把Session ID作為Cookie保持在瀏覽器中,現在絕大多數瀏覽器都會把Cookie功能打開,但如果用戶禁止了Cookie呢?Java Servlet API中提出了另外一種機制,Servlet容器可以重寫客戶requst的URL,把Session ID添加到URL信息中,HttpServletResponse接口提供了這樣的方法:public String encodeURL(String url)-先判斷如果沒有啟用Session,例如jsp中<%@ page session="false"%>或執行了session.invalideate(),那么直接返回url,在判斷客戶端師父支持Cookie,如果不支持,就在url中加入Session ID的信息,然后返回修改后的url。
Session的管理
當一個sesson開始時,Servlet容器會創建一個HttpSession對象,在某些情況下把這些Httpsession對象從內存中轉移到文件系統中或數據庫中,需要訪問的時候在把它們載入到內存中來。這樣做的好處有兩點:節約了內存的消耗,當web服務器產生故障時,還可以從文件系統或數據庫中恢復Session的數據。
對于Session的管理,小貓提供了兩個實現類:org.apache.catalina.session.StandardManager和org.apache.catalina.session.PersistentManager。
StandardManager -是默認的方法,當Tomcat服務器重啟或重載的時候,會把Session對象保存到
<%CATALINA_HOME%>/work/Catalina/honstname/applicatonname/SESSIONS.ser(默認值)文件中,每個對象對應一個文件,以Session ID為文件名,例如:
<
Context?
path
="/helloapp"
?docBase
="helloapp"
?debug
="0"
?reloadable
="true"
>
??? <
Manager?
className
="org.apache.catalina.session.StandardManager"
?debug
="0"
?
????? maxActiveSessions="-1" checkInterval="60"
?/
>
</
Context
>
參數說明:checkInterval-檢查session是否過期的時間間隔,以秒為單位,缺省值是60秒;
maxActiveSessions-可處于活動狀態的session數。
PersistentManager -提供了更加靈活的管理方式,具有容錯能力,可以及時把Session備份到Session Store中,可以控制內存中Session的數量。
小貓還提供了實現持久化Session Store的接口,org.apache.catalina.Store,目前提供了兩個具體實現類:org.apache.catalina.FileStore和org.apache.catalina.JDBCStore。
server.xml中的配置File Store -
<
Context?
path
="/helloapp"
?docBase
="helloapp"
?debug
="0"
?reloadable
="true"
>
??? <
Manager?
className
="org.apache.catalina.session.PersistentManager"
?debug
="0"
?saveOnRestart
="true"
?
????????? maxActiveSessions
="-1"
?minIdleSwap
="-1"
?maxIdleSwap
="-1"
?maxIdleBackup
="-1"
?
>
??? <
Store?
className
="org.apache.catalina.session.FileStore"
?directory
="mydir"
/>
??? </
Manager
>
</
Context
>
參數說明:saveOnRestart-服務器關閉時,是否將所有的session保存到文件中;
maxActiveSessions-可處于活動狀態的session數;
minIdleSwap/maxIdleSwap-session處于不活動狀態最短/長時間(s),sesson對象轉移到File Store中;
maxIdleBackup-超過這一時間,將session備份。(-1表示沒有限制)
JDBCStore配置的區別:
<
Store?
calssName
="org.apache.catalina.JDBCStore"
?driverName
="com.mysql.jdbc.Driver"
?
??? connectionURL
="jdbc:mysql://localhost/tomsessionDB?user=root&password="
?
??? sessionTable
="tomcat_session"
?sessionIdCol
="session_id"
?sessionDataCol
="session_data"
?
??? sessionValidCol
="session_valid"
?sessionMaxInactiveCol
="max_inactive"
?
??? sessionLastAccessedCol
="last_access"
?sessionAppCol
="app_name"
?checkInterval
="60"
?debug
="99"
?
/>
Session失效時間的設定
在web.xml文件中,位于<servlet-mapping>和<welcome-file-list>元素之間加入如下代碼,單位為分鐘:
<
session-config
>
???
??? <
session-timeout
>
60
</
session-timeout
>
</
session-config
>
Tomcat的admin平臺和manager平臺
這是Tomcat中自帶的兩個Web應用,位于<%CATALINA_HOME%>/server/webapps/admin(manager),訪問地址是http://localhsot:8080/admin(manager)。要訪問這兩個Web應用,需要在
<%CATALINA_HOME%>/conf/tomcat-users.xml中添加如下內容:
<user username="admin" password="1234" role="admin"/>?????????? //對應admin Web應用
<user username="manager" password="1234" role="manager"/>?? //對應manager Web應用
admin平臺把所有可配置的信息分為三類:Tomcat Server、Resources、User Definition。
Tomcat Server-相當于server.xml中的<Server>元素及其子元素,<Service>、<Host>、<Context>、<Resources>、<Date Source>。
Resources-相當于server.xml中的<GlobalNamingResources>,共有四種資源:Date Source(JNDI數據源)、Mail Sessioin(JNDI Mail Session資源)、Environment Entry(環境變量)、User Database(安全域中的用戶數據庫)。
User Definition-與tomcat-users.xml相對應。
manager平臺-列出來所有Web應用和狀態,并提供了Start、Stop、Reload、 Undeploy命令,還可以發布
<%CATALINA_HOME%>/webapps目錄下的Web應用或系統文件任意位置的WAR文件。
posted @
2006-06-07 14:41 崛起的程序員 閱讀(245) |
評論 (0) |
編輯 收藏
解決思路:
配置web工程web.xml加上
? <mime-mapping>
??? <extension>doc</extension>
??? <mime-type>application/msword</mime-type>
? </mime-mapping>
? <mime-mapping>
??? <extension>xls</extension>
??? <mime-type>application/vnd.ms-excel</mime-type>
? </mime-mapping>
修改后非常注意的要清空緩存這樣才會彈出保存還是打開的窗口否則打開還是亂碼.
posted @
2006-06-02 12:32 崛起的程序員 閱讀(1083) |
評論 (0) |
編輯 收藏
在weblogic下面增加虛擬目錄
修改weblogic.xml
<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app xmlns="
http://www.bea.com/ns/weblogic/80
" xmlns:xsi="
http://www.w3.org/2001/XMLSchema-instance
" xsi:schemaLocation="
http://www.bea.com/ns/weblogic/80
http://www.bea.com/ns/weblogic/80/weblogic-web-app.xsd
http://java.sun.com/xml/ns/j2ee
http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd
">
? <context-root>webdoc</context-root>
? <virtual-directory-mapping>
?<local-path>c:/word/doc</local-path>
?<url-pattern>/*</url-pattern>
? </virtual-directory-mapping>
</weblogic-web-app>
posted @
2006-06-01 15:49 崛起的程序員 閱讀(2505) |
評論 (3) |
編輯 收藏
??????????????????????????????????????
使用Spring來創建一個簡單的工作流引擎?????????????????????
spring是支持控制反轉編程機制的一個相對新的框架。本文把spring作為簡單工作流引擎,將它用在了更加通用的地方。在對工作流簡單介紹之后,將要介紹在基本工作流場景中基于Spring的工作流API的使用。
許多J2EE應用程序要求在一個和主機分離的上下文中執行處理過程。在許多情況下,這些后臺的進程執行多個任務,一些任務依賴于以前任務的狀態。由于這些處理任務之間存在相互依賴的關系,使用一套基于過程的方法調用常常不能滿足要求。開發人員能夠利用Spring來容易地將后臺進程分離成活動的集合。Spring容器連接這些活動,并將它們組織成簡單的工作流。
在本文中,簡單工作流被定義成不需要用戶干預,以一定順序執行的任意活動的集合。然而,我們并不建議將這種方式代替存在的工作流框架。在一些場景中,需要更多的用戶交互,例如基于用戶輸入而進行的轉向,連接或傳輸,這時,比較好的方法是配用一個單獨的開源或者商業的工作流引擎。一個開源項目已經成功地將更復雜的工作流設計集成到spring中。
如果你手上的工作流任務是簡單的,那么,與功能完備的獨立工作流框架相比,簡單工作流的策略就會變得有意義,特別地,如果已經使用了spring,這種快速實現可以保證時間不會變得更加漫長。此外,考慮到spring輕量級的控制反轉容器的特點,spring在資源負載上減少了資源負載。
這篇文章簡短地從編程主題的角度介紹工作流。通過使用工作流的概念,spring被用來作為驅動工作流引擎的框架。然后,討論了生產部署選項。現在,讓我們從工作流的設計模式和相關背景信息來介紹簡單工作流的思想吧。
簡單工作流
工作流模型是一個早在70年代就有人開始研究的主題,許多開發者都試圖創建工作流模型規范。W.H.M. van der Aalst等人寫了《工作流模型》白皮書(2003年7月),它成功地提煉出一組設計模式,這些設計模式準確地將大多數通用的工作流場景建模。當中,最普通的工作流模式是順序模式 (Sequence pattern)。順序工作流模式滿足了簡單工作流的設計原則,并且由一組順序執行的活動組成。
UML(統一建模語言)活動圖通常被用來作為一個機制對工作流建模。圖1顯示了一個基本的使用標準UML活動圖對順序工作流過程的建模過程。
圖 1順序工作流模式
順序工作流是一個在J2EE中流行的標準工作流模式。J2EE應用程序在后臺線程中,通常需要一些順序發生的事件或者異步事件。圖2中的活動圖描述了一個簡單的工作流,用來通知感興趣的旅行者,他們感興趣的目的地的機票價格已經下降的事件。
圖 2.機票價格下降的簡單工作流
圖1中的航線工作流負責創建和發送動態的email通知。過程中的每一步表示了一個活動(activity)。在工作流處于活動之前,一些額外事件必須發生。在這個例子中,事件是飛行路線費率的減少。
讓我們來簡要的看一下航線工作流的業務邏輯。如果第一個活動找不到對費率減少通知感興趣的用戶,那么整個工作流就被取消。如果發現了感興趣的用戶,那么接下來的活動繼續執行。隨后,一個XSL(擴展樣式表)轉換生成消息內容,之后,記錄審計信息 (audit information)。最后,工作流試圖通過SMTP服務器發送這個消息。如果這個任務沒有錯誤地完成,便在日志中記錄成功的信息,進程結束。但是,如果在和SMTP服務器通訊時發生了錯誤,一個特別的錯誤處理例程將要管理這些錯誤。錯誤處理代碼將會試著去重新發送消息。
考慮這個航線的例子,一個明顯的問題是:你怎么樣有效地將順序處理過程分解為單獨的活動?這個問題被spring巧妙的處理了。下面,讓我們快速地討論spring的反轉控制框架。
控制反轉
Spring通過使用spring容器來負責控制對象之間的依賴關系,使得我們不再對對象之間的依賴負責。 這種依賴關系的實現就是大家所知道的控制反轉(IoC)或依賴注射。參見Martin Fowler's "Inversion of Control Containers and the Dependency Injection Pattern"(martinfowler.com, 2004年2月)得到關于控制反轉和依賴注射的更加深入的討論。通過管理對象之間的依賴關系,spring就不需要那些只是為了使類能夠相互協作,而將對象粘合的代碼。
作為spring beans的工作流組件
在進一步討論之前,現在是簡要介紹spring中主要概念的恰當時候。接口ApplicationContext是從接口BeanFactory繼承的,它被用來作為在spring容器內實際的控制實體和容器。
ApplicationContext負責對一組作為spring beans的一組bean的初始化,配置和生命期管理。我們通過裝配在一個基于XML的配置文件中的spring beans來配置ApplicationContext。這個配置文件說明了spring beans互相協作的本質特點。這樣,用spring的術語來說,與其他spring beans交互的spring beans就被叫著協作者(collaborators)。缺省情況下,spring beans是作為單例存在于ApplicationContext中的,但是,單例的屬性能夠被設置為false,從而有效地改變他們在spring中調用原型模式時的行為。
回到我們的例子,在飛機票價下降的時候,一個SMTP發送例程的抽象就被裝配在工作流過程例子中的最后的活動(例子代碼可以在 Resources中得到)。由于是第5個活動,我們命名它為activity5。要發送消息,activity5就要求一個代理協作者和一個錯位處理句柄。
????? class="org.iocworkflow.test.sequence.ratedrop.SendMessage">
?????
???????? BR>?????
?????
????????
?????
?? /FONT>
將工作流組件實施成spring beans產生了兩個令人喜悅的結果,就是容易進行單元測試和很大程度上可重用能力。IoC容器的特點明顯地提供了有效的單元測試。使用像spring這樣的Ioc容器,在測試期間,協作者之間的依賴能夠容易的用假的替代者替代。在這個航線的例子中,能夠容易地從唯一的測試ApplicationContext中檢索出像activity5活動這樣的spring bean。用一個假的SMTP代理SMTP服務器,就有可能單獨地測試activity5。
第二個意外的結果,可重用能力是通過像XSL轉換這樣的工作流活動實現的。一個被抽象成工作流活動的XSL轉換現在能夠被任何處理XSL轉換的工作流所重用。
裝配工作流
在提供的API中(從Resources下載),spring控制了一些操作者以一種工作流的方式交互。關鍵接口如下:
Activity: 封裝了工作流中一個單步業務邏輯
ProcessContext:在工作流活動之間傳遞具有ProcessContext類型的對象。實現了這個接口的對象負責維護對象在工作流轉換中從一個活動轉換到另一個活動的狀態。
ErrorHandler: 提供錯誤處理的回調方法。
Processor: 描述一個作為主工作流線程的執行者的bean。
下面從例子源碼中摘錄的代碼是將航線例子裝配為簡單工作流過程的spring bean的配置。
??
?????
????????
???????????
???????????
???????????
???????????
???????????
???????? BR>?????
?????
???????? BR>????? /property>
?????
???????? org.iocworkflow.test.sequence.ratedrop.RateDropContextBR>?????
?? /property>
SequenceProcessor類是一個對順序模式建模的具體子類。有5個活動被連接到工作流處理器,工作流處理器將順序執行這5個活動。
與大多數過程式后臺進程相比,工作流的解決方案真正的突出了高度強壯的錯誤處理。錯誤處理句柄可以單獨地處理每個活動。這種類型的句柄在單一活動級別提供了細致的錯誤處理。如果沒有單獨處理單個活動的錯誤處理句柄,那么全局工作流處理器的錯誤處理句柄將會處理出現的問題。例如,如果在工作流處理過程中的任意時刻,一個沒有被處理的錯誤出現了,那么它將會向外傳播,被使用defaultErrorHandler屬性裝配的ErrorHandler Bean處理。
更復雜的工作流框架將工作流轉換之間的狀態持久化存儲到數據庫中。在這篇文章中,我們僅僅對狀態轉換是自動完成的工作流感興趣。狀態信息僅僅在實際工作流運行時在ProcessContext中得到。在ProcessContext中,你僅僅能看到ProcessContext的接口的兩個方法:
public interface ProcessContext extends Serializable {
????? public boolean stopProcess();???
????? public void setSeedData(Object seedObject);
?? }
用于航線例子工作流的具體的ProcessContext類是RateDropContext類。RateDropContext類封裝了用于執行航線費率降低工作流必須的數據。
到現在為止,經由缺省的ApplicationContext的作用,所有bean實例都已經成了單例。但是,對于每一個航線工作流的調用,我們必須創建一個新的RateDropContext類的實例。為了處理這種需求,需要配置SequenceProcessor,采用全限定類名作為processContextClass屬性的值。對于每個工作流的執行,SequenceProcessor使用指定的類名從spring檢索ProcessorContext類的一個新的實例。為了使這種機制能夠起作用,非單件的spring bean或者類型org.iocworkflow.test.sequence.simple.SimpleContext的原型必須存在于ApplicationContext中(完整的列表,參見rateDrop.xml)。
播種工作流
既然我們知道怎樣使用spring來組裝一個簡單的工作流,就讓我們集中精力使用種子數據(seed data)示例工作流的過程。要明白怎樣開始工作流,看一看在實際接口Processor上表現的方法:
public interface Processor {
????? public boolean supports(Activity activity);
????? public void doActivities();
????? public void doActivities(Object seedData);
????? public void setActivities(List activities);
????? public void setDefaultErrorHandler(ErrorHandler defaultErrorHandler);
?? }
大多數情況下,工作流需要一些初始化激活才能開始。開始一個處理過程有兩個選項:doActivities(ObjectseedData)方法或者無參數的doActivities()。下面的代碼列表是包含在樣例代碼中為SequenceProcessor而實現的doActivities():
public void doActivities(Object seedData) {
?? //Retrieve injected by Spring
?? List activities = getActivities();
?? //Retrieve a new instance of the Workflow ProcessContext
?? ProcessContext context = createContext();
?? if (seedData != null)
????? context.setSeedData(seedData);
?? //Execute each activity in sequential order
?? for (Iterator it = activities.iterator(); it.hasNext();) {
????? Activity activity = (Activity) it.next();
????? try {
??????????? context = activity.execute(context);
????? } catch (Throwable th) {
???????? //Determine if an error handler is available at the activity level
???????? ErrorHandler errorHandler = activity.getErrorHandler();
???????? if (errorHandler == null) {
??????????? getDefaultErrorHandler().handleError(context, th);
??????????? break;
???????? } else {
??????????? //Handle error using default handler
??????????? errorHandler.handleError(context, th);
???????? }
????? }
??????????? //Ensure it's ok to continue the process
????? if (processShouldStop(context, activity))
???????? break;
????? }
?? }
在這個航空費用減少的例子中,工作流過程的種子數據包括航線信息和費率減少的信息。使用容易測試的航線工作流例子,通過doActivities(Object seedData)方法發出種子數據并激活一個單一的工作流過程是簡單的:
BaseProcessor processor = (BaseProcessor)context.getBean("rateDropProcessor");
?? processor.doActivities(createSeedData());
這些代碼是從包含在這篇文章中的測試例子中摘錄的。rateDropProcessor Bean是從ApplicationContext中檢索來的。rateDropProcessor實際上是裝配成SequenceProcessor的實例來處理順序執行。createSeedData()方法實例化一個對象,這個對象封裝了初始化航線工作流所需要的所有種子數據。
Processor選項
雖然包含在源代碼中的Processor具體的子類僅僅是SequenceProcessor,但是,許多Processor接口的實現也是可以想象得到的。可以開發其他工作流處理過程子類來控制不同的工作流類型,例如,另一種像并行切割模式那樣有著變化的執行路徑的工作流。對于簡單工作流來說,因為活動的順序是預先決定了的,所以SequenceProcessor是好的選擇。盡管沒有被包括進來,對于使用基于spring的簡單工作流的實現來說,排他選擇模式是另一個好的選擇。當使用排他選擇模式時,在每個活動執行之后,Processor具體類就會訊問ProcessorContext,接下來將要執行哪一個活動。
注:有關并行切割,排他選擇和其他工作流模式的更多信息,請參看W.M.P. van der Aalst等人寫的《工作流模式》一書。
啟動工作流
考慮到工作流過程常常需要異步執行的特點,使用分離的執行線程來啟動工作流就變得有意義了。對于工作流的異步啟動而言,有好幾個選項;我們主要集中在其中的兩個:積極地檢測(actively polling)一個隊列來啟動工作流,或者使用通過ESB(enterprise service bus, 企業服務總線)的事件驅動方式來啟動工作流,而Mule就是ESB的一個開源項目(關于Mule的更多信息,請參加"Event-Driven Services in SOA"(JavaWorld, 2005年1月)。
圖3和圖4描繪了兩種啟動策略。圖3中,積極檢測在工作流中第一個活動經常檢查資源的情形下發生,比如數據源或POP3郵件帳戶。如果圖3中的積極檢測發現有任務等待處理,那么啟動就會開始。
圖 3. 通過積極檢測來啟動工作流
另一方面,圖4表示了使用JMS(JAVA消息服務)的J2EE應用程序把事件放到隊列上的情形。一個通過ESB配置的事件監聽器收到圖4中的事件,并且開始工作流,這樣,啟動工作流過程。
圖 4. 通過ESB事件來啟動工作流
http://searchwebservices.techtarget.com.cn/tips/110/2127110.shtml
使用所提供樣例的代碼,讓我們更詳細的看看主動選擇啟動方式與事件驅動的啟動方式。
積極檢測
積極檢測是一種花費較少的啟動工作流過程的方案。SequenceProcessor足夠靈活,以使得能夠通過平滑的選擇工作來進行啟動過程。盡管并不令人滿意,在沒有時間進行事件驅動子系統的配置和部署的許多情景中,積極檢測是明智的選擇。
使用Spring的ScheduledTimerTask,檢測模式就能夠容易地裝配。缺點就是必須創建額外的活動來進行檢測。這個檢測活動必須被設計來訊問某些實體,如數據庫表,pop郵件帳戶,或者Web服務,然后決定新的工作是否等待參與到工作流中。
在所提供的例子中,PollingTestCase類實例化一個基于檢測的工作流過程。使用一個有著積極檢測處理過程與事件驅動的啟動過程的不同之處在于,spring支持doActivities()方法的無參數版本。相反地,在事件驅動的啟動中,啟動處理過程的實體通過doActivities(Object seedData)方法提供了種子數據來啟動工作流。檢測方法的另一個缺點是:資源不一定能夠被重復地使用。依賴于應用程序環境,這種資源的消耗是不可接受的。
下面代碼例子演示了使用積極檢測來控制工作流啟動的一個活動:
public class PollForWork implements Activity
{
?? public ProcessContext execute(ProcessContext context) throws Exception {
????? //First check if work needs to be done
????? boolean workIsReady = lookIntoDatabaseForWork();
????? if (workIsReady) {
???????? //The Polling Action must also load any seed data
???????? ((MyContext) context).setSeedData(createSeedData());
????? } else {
???????? //Nothing to do, terminate the workflow process for this iteration
???????? ((MyContext) context).setStopEntireProcess(true);
????? }
????? return context;
?? }
}
此外,包含在例子代碼的單元測試中的PollRates類提供了一個主動選舉啟動的可以運行的例子。PollRates模擬了對于航線費率下降的重復檢查。
通過ESB的事件驅動啟動工作流
理想地,一個包含了適當的種子數據的線程能夠異步地啟動工作流。這種情況的一個例子是收到從JAVA消息服務隊列的消息。一個監聽JMS隊列或者主題的客戶會收到通知,這個通知告知處理應該在onMessage()方法中開始工作流。然后,通過使用Spring和doActivities(Object seedData)方法就能夠獲得工作流處理器Bean。
使用ESB,實際用于發送啟動事件的機制能夠恰當地從工作流處理器中分離出來。開源項目Mule ESB有緊湊地和Spring相集成的好處。任意傳送機制,比如JMS,JVM,或者POP3郵箱都能夠發起事件的傳播。
工作流的連續運行
工作流引擎后臺進程應該能夠沒有干擾地連續運行。對于正在運行的基于spring的工作流單一進程來說好,有幾個選項。一個有著main()方法的簡單Java類就足夠演示與這篇文章伴隨著的單元測試中的例子了。一個更加可靠的用于部署的機制是嵌入工作流到某種形式的J2EE組件中。Spring很好地支持和J2EE兼容的web應用程序歸檔或者war文件的集成。基于Java管理附件(JMX)服務歸檔和JBoss應用服務器(更多信息,參見JBoss homepage)支持的sar文件是更加合適的可部署組件,這種更合適的可部署組件也能夠被用來將部署歸檔。在JBoss 4.0中,sar文件已經被大家所知道的deployer的格式所取代了。
例子代碼
打包成zip格式的例程代碼最好是用Apache Maven來使用它們。你能夠在主源代碼目錄src/java找到API。src/java目錄中有三個單元測試,包括:SimpleSequenceTestCase,RateDropTestCase和PoolingTestCase。要運行所有這些測試,在命令行shell中鍵入maven test,然后在編譯和運行之前,Maven將會下載所有必需的jar文件。實際的XSL轉換將會發生在兩個測試中,它們的結果被管道輸出到控制臺。鍵入maven test:ui來拉出圖形化的測試運行器,然后選擇你想要運行的測試,并且觀察控制臺的結果。
結論
在這篇文章中你已經通過設計模式看到了工作流過程種類,在這些模式中,我們主要集中介紹了順序模式。通過使用接口,我們來對基本工作流組件建模。通過裝配多個接口實現到Spring,實現一個順序工作流。最后還討論了啟動和部署工作流的不同選項。
這里所提出的簡單工作流技術肯定不是最終的和革命性的。但是,使用Spring來實現像工作流這樣的通用任務是一個通過使用IoC容器而獲得的效率的好的示例。由于減少了粘合性代碼的需要,Spring在保持面向對象的約束同時,減少面向對象操作麻煩的程度。
http://macrochen.blogdriver.com/macrochen/1088243.html
什么是工作流引擎(Workflow Engine )- -
所謂工作流引擎是指workflow作為應用系統的一部分,并為之提供對各應用系統有決定作用的根據角色、分工和條件的不同決定信息傳遞路由、內容等級等核心解決方案。例如開發一個系統最關鍵的部分不是系統的界面,也不是和數據庫之間的信息交換,而是如何根據業務邏輯開發出符合實際需要的程序邏輯并確保其穩定性、易維護性(模塊化和結構化)和彈性(容易根據實際業務邏輯的變化作出程序上的變動,例如決策權的改變、組織結構的變動和由于業務方向的變化產生的全新業務邏輯等等)。 Workflow 引擎解決的就是這個問題:如果應用程序缺乏強大的邏輯層,勢必變得容易出錯(信息的路由錯誤、死循環等等)。
就好比一輛汽車,外表做得再漂亮,如果發動機有問題就只是一個擺設。應用系統的彈性就好比引擎轉速方面的性能,加速到100 公里需要1 個小時(業務流程發生變動需要進行半年的程序修改)還能叫好車嗎?引擎動不動就熄火(程序因為邏輯的問題陷入死循環)的車還敢開嗎?
工作流解決方案與傳統管理軟件的關系傳統的管理軟件注重解決企業應用層現存的問題(例如提高企業的資源配置率或提高單一員工的生產效率)。例如:EXCEL 可以提高員工畫表格的效率、財務軟件可以規范財務人員的工作并提高帳目查詢的效率、CRM 可以規范客戶管理從而使客戶資源掌握在公司手中而不是被一部分業務人員把持并提高客戶響應時間、ERP 解決的是如何配置企業資源:使企業的人力資源、財力資源和物資資源能夠根據業務的需求實現最大化配置。 workflow 關注的是如何縮短流程閑置時間,從而提高企業的業務處理能力并使企業能夠關注于真正對企業有意義的增值業務上。從建立企業神經系統的角度也許更能理解兩者的區別。傳統軟件不能解決工作流的問題,例如ERP 關注的是企業的資源配置,但不可能解決資源傳輸過程中的損耗和降低傳輸(流程)的成本;同樣workflow也不能完全解決傳統管理軟件所能解決的問題,例如對生產管理的MRP 系統所能解決的生產過程控制通過workflow很難實現。但一個好的傳統軟件如果希望能自動化地在整個企業中應用起來,必須有一個強大的邏輯層,用以解決信息傳遞的邏輯判斷和自動流轉,這個時候就需要workflow的平臺。所以說: 1.workflow 和傳統管理軟件不是同一種軟件,不具可比性; 2.workflow 對于已經有傳統管理軟件的企業的作用非常明顯,可以籍此平臺整合企業的各種應用系統,使之成為一個完整的企業級應用,也就是通常所說的EAI. 3. 具備workflow功能的管理軟件(workflow與傳統管理軟件的結合)對于傳統管理軟件有絕對的優勢;4.workflow可以根據企業的需要開發解決信息傳遞問題的流程以及幫助企業開發與現有應用系統的接口
工作流自動化并不復雜因為下述幾個原因,工作流自動化業界有" 適合處理復雜業務流程" 的名聲。
1.常規工作流自動化軟件包及其部署相當昂貴。通常,伴隨產品的是長時期的咨詢關系。所以為了非常簡單的業務流程購買和部署軟件是被不被采納的。這些軟件通常只被用于復雜、關鍵和控制成本相對較高而工作流自動化帶來的效益明顯的量產型工作流應用。因此經銷商和用戶都會不自覺地關注于將復雜的業務問題自動化。 2. 處于類似原因,工作流研究人士首先會關注解決了哪些復雜的業務流程問題。
而對于大多數案例而言,為解決簡單工作流程問題部署自動化軟件的成本顯然是不經濟的。這里遵循一條簡單的道理:走之前必須先會爬,跑之前必須先會走。 3. 最后一條原因,也是"IT 業的尷尬".總經理對IT部門經理工作衡量的標準就是:能夠解決復雜問題的能力。自然,IT經理就會不遺余力地解決那些復雜的問題,他們的方案通常也就復雜而且昂貴。
所有這些目前都在改變。針對桌面電腦的應用方案快速發展以及工作流解決方案的發展使解決日常工作流程問題成為可能。費用不再昂貴,部署更為簡便。事實上,企業越來越意識到工作流的重要性,同時在部署復雜關鍵的流程自動化之前,愿意從一些簡單的流程入手積累經驗。
工作流會成為操作系統的一部分嗎?
有人認為工作流會成為操作系統平臺(例如WINDOWS 平臺)的一部分。我們的觀點是,基于下述幾個原因,在可預見的未來,工作流不會成為操作系統的一部分: 1. 擴展表格、文字處理程序和數據庫存在了20多年,成了家喻戶曉的名詞。這些技術被廣泛理解和應用,也相應形成了各自的標準和相關術語。然而因為很多原因,直到今天這些技術也沒有成為操作系統的一部分。最重要的原因之一是用戶需要差異和選擇的自由。相比較而言,工作流自動化軟件是較新的技術,也更有差異性、不易被廣泛理解并且比這些技術更為先進。因為工作流程的差異性和復雜性,工作流自動化的用戶需要更多的選擇空間。
2.財務軟件包從電腦發明后就迅速普及了。這是實施、術語和規則被普遍接受的另一個領域。然而至今也沒有哪種操作系統吹噓集成了多少財務軟件的功能。而工作流自動化軟件比財務軟件更為復雜和有差異性。 3. 操作系統提供商,例如微軟和Sun ,不會為了使其系統具備工作流自動化的功能而大量改變他們現有的系統。他們有什么必要為工作流自動化軟件投入開發和支持的成本呢? 4. 操作系統是為常規條件設計并使之最優化。正因如此,目前操作系統的開發成本幾乎都要上億美元。業務流程十分復雜并充滿了例外情況,如在操作系統中內嵌工作流自動化程序會極大地增加開發成本和難度。因此,即便操作系統提供商決定做工作流軟件,也會是巨額投入開發一套新的操作系統,而不是將工作流嵌入。
事實上,今天的很多優秀的工作流解決方案集成了短信息、頁面服務、目標管理、文件管理和其他一些操作系統才提供的服務。
工作流自動化的主要成分工作流自動化如今成了管理的一句時髦話。市面上也有很多號稱能激活工作流的自動化產品。只要他們的應用程序支持基本的E-mail功能,賣主就會隨意地把" 激活工作流" 作為標簽貼在產品上。然而,這類產品和真正工作流自動化軟件之間的差別就如同寫字版和Word之間的差別。我們相信,應用程序只有具備了下列主要特征,才能稱其為工作流自動化解決方案:
能夠畫出工作流程圖,當然以圖形化界面設計的為佳;能為每個步驟設計電子表格;能將外部應用程序結合為工作流自動化的一部分;能與電子表格及企業數據庫相連接;能設計基于復雜業務規則的條件型路由的工作流程圖,最好無須編程;能根據功能、用戶名稱或上下級關系按規則傳遞信息;能夠監控工作流執行狀況;能夠對工作流進行調節;能夠模擬并測試工作流的行為;工作流的應用必須支持多用戶并具高度可靠性;工作流的應用必須支持內部網或英特網及跨多種平臺。
網友討論工作流應該是一個中間件而不應該是一個完整的系統。工作流應該整合到其他系統中而不是單獨使用。
工作流要完成的核心功能有流程設計,流程執行,流程和線程的調度,任務的分派與通知,集成已有信息系統(很多人忘了)。
工作流應該提供對組織機構,用戶,權限管理,流程,任務的管理能力,但是對這些管理能力最基本實現方式是提供API ,而不是一個管理系統,即使把這些管理作為一個管理系統來實現(A ),也主要是用于演示,因為當工作流用于其它系統(B ),因為B 需要一個統一的管理界面,所以通常不會直接使用A.而表單設計,報表之類根本就是外圍功能,是二次開發商的任務。
我基本贊同wangtaoyy 的說法,再補充一點。我覺得工作流與其說是中間件,還不如說是一個應用整合和集成的框架。類似在j2ee規范下各產商開發的應用服務器,工作流也應當是在wfmc標準下開發出來的" 容器" ,只要是滿足了標準的應用程序或組件都能夠在這個" 容器" 中按照預定的規則被調度和執行。我認為理想情況下工作流系統不應該提供API 作二次開發,工作流的內部對基于工作流的應用程序應當是完全不透明的,工作流應當提供給開發者的是一個類似于J2EE那樣的標準,一套編程模型和接口模型。開發者在這個模型下去實現那些接口,開發出應用組件,再利用工作流提供的管理器進行" 注冊".總而言之,對開發者而言,工作流是黑箱,他需要做的事情是開發標準組件,在工作流提供的UI管理工具中配置業務流程,包括業務過程、資源、權限、時間、規則等等。
1. j2ee 應用服務器也是中間件的一種。
2. 工作流要做成j2ee哪樣的標準還是比較困難的, j2ee 重點在于提供開發全新系統的能力,所以可以制定比較好的容器- 組件標準,而工作流的重點是整合已經存在的系統,要在這些各式各樣的老系統上強加標準是不現實的。
3.工作流應該提供api ,因為其他系統中的一些事件可能會啟動一個流程,或者觸發其他與流程相關的東西
工作流分為兩種類型,一種是嵌入式的,另一種是非嵌入式的。這在WFMC的文檔中已經有所介紹,大家可以找找看一下。按照工作流管理聯盟的文檔,大家說的都沒有什么錯誤,只是側重點不同。wangtaoyy 的觀點傾向于前者,而coffeewoo 的觀點傾向于后者。
我的看法并不是趨向于嵌入式工作流。我理解的工作流提供的api 并不是一般軟件包的API ,而是一種服務方式的API ,類似于操作系統中的系統調用。
我們在軟件中大量使用了操作系統提供的系統調用API ,但是操作系統并不是嵌入到我們軟件系統中的。我認為工作流系統與操作系統有很強的可比性,只是工作流層次更高。比如流程設計相當于編程,模型相當于程序,流程實例相當于進程,流程分支相當于線程,操作系統要對進程和線程進行調度,工作流引擎要對流程實例和分支進行調度,操作系統和工作流系統都應該對內存進行管理避免耗盡系統內存,操作系統提供系統調用API 而工作流引擎提供工作流API.何其相似。
從功能的角度看:工作流系統的本職工作就是管理和控制業務流程,例如:流程實例的啟動、停止;環節實例的啟動、結束;任務的分配等等。從工作流系統的組成看:工作流系統應該包括流程引擎、流程定義工具、運行管理工具、api 系統。工作流系統應該該不包括表單定義、組織機構定義及其管理、權限管理、數據流管理等等。
工作流系統雖然不包括上述功能,但是工作流系統一定會和上述功能發生交互關系,所以好的工作流產品并不是一個包辦上述功能的產品,而是一個設計良好的能夠和上述功能交互的系統。從和其他系統的關系看待工作流:如果站在基礎業務平臺的角度,那么,工作流系統、組織機構管理系統、表單自定義系統、權限管理系統、數據流管理系統、報表系統都是這個基礎業務平臺的服務。業務功能系統在運行的過程中會調用這些服務,這些服務之間本身也可能互相調用。例如:工作流服務和組織機構管理服務之間的關系就非常密切,盡管如此,如果認為工作流系統一定包含組織機構管理系統應該是不正確的。在oa系統中,表單自定義好像比較重要,而且流程常常需要引用表單上的數據,但是表單自定義絕對不是工作流系統的組成部分。流程在運行的過程中可能跨多個數據庫系統,任務在流轉的過程中需要“攜帶”大量的業務數據,但是這些也不是工作流要做的事情,完成這些工作的系統我稱之為“數據流管理系統”。總之:從功能的角度,所有的功能都是必要的,但是從技術的角度,這些功能不可以做到一個“鐵板一塊”的所謂的“工作流”里面去。從技術發展的趨勢看:工作流系統很可能發展成為一個類似關系型數據庫管理系統的專職的系統。我那個工作流東東還在改進中,希望作出一個設計合理的(決對不是強行coding出來的),工程實用的東西出來
posted @
2006-06-01 14:12 崛起的程序員 閱讀(1981) |
評論 (0) |
編輯 收藏
Note for Eclipse 3.1 Update Manager users: you can use special Eclipse update site for most plugins presented here. Go to "Help -> Software Updates -> Find and Install... -> Search for new features to install -> Next -> New Remote Site..." and use the http://andrei.gmxhome.de/eclipse/ as url.
Extended VS Presentation plugin for Eclipse: examples
Enable/disable Extended VS Presentation here
Set custom properties here (this settings will override current theme settings)
?
Change selected theme properties here (this settings will override current theme settings)
posted @
2006-05-31 15:50 崛起的程序員 閱讀(300) |
評論 (0) |
編輯 收藏
凡是接觸過
Java
的人都知道
JRE
的概念,即
Java
運行時環境(
Java Runtime Environment
),因為它是運行
Java
程序必不可少的(除非程序用
GCJ
等編譯,但我懷疑這樣處理后還能不能稱之為“
Java
程序”了)。
Java
喊出的帶有標志性的口號“
Write Once
,
Run Anywhere
(一次編寫,到處運行)”(記得某老師給俺們上課講到這里時還不忘幽一默:到處運行?沒有計算機就運行不了……),正是建立在
JRE
的基礎之上。何以實現?就是在
Java
應用程序和操作系統之間增加了一虛擬層——
JRE
。程序源代碼不是直接編譯、鏈接成機器代碼,而是先轉化到字節碼(
bytecode
)這種特殊的中間形式,字節碼再轉換成機器碼或系統調用。前者是傳統的編譯方法,生成的機器代碼就不可避免地跟特殊的操作系統和特殊的機器結構相關,很多裝雙系統的用戶無法在
Linux
運行
Windows
下的大型游戲,心里那個郁悶(于是很多虛擬軟件和模擬程序應運而生)。而
Java
程序的字節碼文件可以放到任意裝有
JRE
的計算機運行,再由不同
JRE
的將它們轉化成相應的機器代碼,這就實現了
Java
程序的可移植性。這樣程序員也不用去關心程序運行的具體環境,而可以專心編寫軟件。這種分層抽象、隱藏細節的思想在計算機科學中處處可見,比如機器組織結構的設計、網絡協議的實現等。
Pascal
語言的發明者
Niklaus Wirth
,就富有預見性地指出應該有這樣一種可移植的語言,其生成的中間代碼可以在一臺假想的機器(
a hypothetical machine
)上運行。而
Java
虛擬機(
Java virtual machine
或
JVM
)就是這樣的一臺機器,它模擬實際處理器的結構,解釋字節碼。怎么一會說是
JRE
,一會兒又成了
JVM
,兩者是否同物不同名?
回答是否定的。
JVM
是
Java
平臺的基礎,和實際的機器一樣,它也有自己的指令集,并且在運行時操作不同的內存區域。
JVM
通過抽象操作系統和
CPU
結構,提供了一種與平臺無關的代碼執行方法,即與特殊的實現方法、主機硬件、主機操作系統無關。但是在一些小的方面,
JVM
的實現也是互不相同的,比如垃圾回收算法,線程調度算法(可能不同
OS
有不同的實現)。
JVM
的主要工作是解釋自己的指令集(即字節碼)到
CPU
的指令集或
OS
的系統調用,保護用戶免被惡意程序騷擾。
JVM
對上層的
Java
源文件是不關心的,它關注的只是由源文件生成的類文件(
class file
)。類文件的組成包括
JVM
指令集,符號表以及一些補助信息。
而
JRE
是
Sun
公司發布的一個更大的系統,它里面就有一個
JVM
。
JRE
就與具體的
CPU
結構和操作系統有關,我們從
Sun
下載
JRE
的時候就看到了不同的各種版本。同
JVM
一起組成
JRE
的還有一些
API
(如
awt
,
swing
等)。
JRE
是運行
Java
程序必不可少的。
Over
posted @
2006-05-22 22:30 崛起的程序員 閱讀(715) |
評論 (1) |
編輯 收藏
一、讀大學,究竟讀什么?
??大學生和非大學生最主要的區別絕對不在于是否掌握了一門專業技能,一個經過獨立思考而堅持錯誤觀點的人比一個不假思索而接受正確觀點的人更值得肯定,草木可以在校園年復一年地生長,而我們卻注定要很快被另外一群人替代,盡管每次網到魚的不過是一個網眼,但要想捕到魚,就必須要編織一張網。
??
??二、人生規劃:三岔路口的抉擇
??不走彎路就是捷徑,仕途,商界,學術。在這人生的三岔路口,你將何去何從,與其跟一百個人去競爭五個職位,不如跟一個人去競爭一個職位,學術精神天然的應當與塵囂和喧嘩保持足夠的距離,商場不忌諱任何神話。你也完全可能成為下一個傳奇。
??
??三、專業無冷熱,學校無高低
??沒有哪個用人單位會認為你代表了你的學校或者你的專業,既然是概率,就存在不止一種可能性,如果是選擇學術,冷門專業比熱門專業更容易獲得成就,跨專業幾乎早已成為一種流行一種時尚,大學之間的實力之爭到了考研考場和人才市場原來是那樣的微不足道。
??
??四、不可一業不專,不可只專一業
??千招會,不如一招熟,十個百分之十并不是百分之百,而是零,在這個現實的社會,真正實現個人價值才是最體面最有面子最有尊嚴的事情,要想知道需要學什么,最好的方式就是留意招聘信息,很多專業因為不具備專長的有效性,所以成為了屠龍之術,為什么不將“買一送一”的促銷思維運用到求職應聘的過程中來呢。
??
??五、不逃課的學生不是好學生
??什么課都不逃,跟什么課都逃掉沒什么兩樣,讀大學,關鍵是學會思考問題的方法,逃課沒有錯,但是不要逃錯課,英語角絕對不是學英語的地方,為了英語丟了專業,那就舍本逐末了,招聘單位是用人才的地方,而不是培養人才的地方,既要逃課,又要讓老師給高分。
??
??六、勤工儉學的辯證法
??對于貧困生來說,首先要做的不是掙錢,而是省錢,大部分女生將電腦當成了影碟機,大部分男生將電腦當成了游戲機,在這個處女膜都可以隨意偽造的年代,還有什么值得輕易相信,態度決定一切,當學習下降到次要的地位,大學生就只能說是兼職的學生了。
??
??七、做事不如做人,人脈決定成敗
??學問好不如做事好,做事好不如做人好,會說話,就能減少奮斗三十年,一個人有多少錢并不是指他擁有多少錢的所有權,而是指他擁有多少錢的使用權,一個人賺的錢,12.5%是靠自身的知識,87.5%則來自人脈關系,三十歲以前靠專業賺錢,三十歲以后拿人脈賺錢,你和世界上的任何一個人之間只隔著四個人。
??
??八、互聯網:倚天劍與達摩克利斯之劍
??花兩個小時就寫出一篇天衣無縫的優秀畢業論文,在互聯網領域創業的技術門檻并不高,關鍵的是市場眼光和營銷能力,輕舞飛揚已經紅顏薄命了,而痞子蔡卻繼續跟別的女孩發生著一次又一次的親密接觸,很多大學生的網友遍布祖國大江南北,可他們卻從未主動向周圍的人說一聲:你好,我們可以聊聊嗎。
??
??九、戀愛:花開堪折方須折
??愛情是不期而至的,可以期待,但不可以制造,越是寂寞,越要警惕愛情,既然單身是可恥的,那西門慶是不是應該被評為宋朝十大杰出青年,花開堪折方須折,莫讓鮮花敗殘枝,一個有一萬塊錢的人為你花掉一百元,你只占了他的百分之一;而一個只有十塊錢的人為你花掉十塊,你就成了他的全部。
??
??十、性:上帝死了,眾神在墮落
??愛要說,愛要做,我只有在肉體一下一下的撞擊中才感到快樂。經過之后,將是更大的寂寞更大的空虛,為何要讓別人的虛榮成為對自己的傷害,當她機械地躺在床上張開雙腿,她的父母正在憧憬著女兒的未來,一朝春盡紅顏老,花落人亡兩不知。
??
??十一、考研:痛苦的安樂死
??沒有比浪費青春更失敗的事情了,研究生擴招的速度是30%,也就意味著碩士學歷貶值的速度是30%,同樣是付出三年的努力,你可以讓E1的值增加1,也可以讓E2的值增加2甚至增加3,讀完碩士或博士并不等于工作能力更強,面對13.54萬的成本,你還會毫不猶豫地投資讀研究生嗎,努力就會有結果,但不一定是好結果。
??
??十二、留學:“海龜”變“海帶”
??月薪2500元的工作,居然引得三個“海歸”碩士爭相競聘,對于某些專業而言,去美國留學和去埃塞俄比亞留學沒什么兩樣,既然全世界的公司都想到中國的市場上來瓜分蛋糕,為什么中國人還要一門心思到國外去留學然后給外國人打工。
??
??十三、非統招:養卑照樣處優
??她在中國信息產業界創下了幾項紀錄。她被稱為中國的“打工皇后”。而她不過是一名自考大專生,要想把曾經輸掉的東西贏回來,就必須把自己比別人少付出的努力補上來,非統招生不但要有一定的實力,而且必須掌握一定的技巧,做到揚長避短出奇制勝,路在腳下。好走,走好。
??
??十四、畢業:十面埋伏的陷阱
??母校不把自己當母親,你又何必把自己當兒女,聽輔導班不過是花錢買踏實,人才市場就是一個地雷陣,通過多種方式求職固然沒有錯,但是千萬不要饑不擇食,只要用人單位一說要你交錢,你掉頭就走便是了,這年頭立字尚且不足以為據,更何況一個口頭約定。
??
??十五、求職:做人不要太厚道
??求職簡歷必須突出自己的核心競爭力,求職的時候大可不必像嚴守一那樣“有一說一”,一個人說假話并不難,難的是把假話說到底,并且不露一絲破綻,在填寫自己的特長時,一定要盡可能詳細,一份求職簡歷只要用一張A4紙做個表格就足夠了,面試其實是有規律的,每次面試的時候只要背標準答案就行了。
??
??十六、騎一頭能找千里馬的驢
??美國鐵路兩條鐵軌之間的標準距離是4英尺8.5英寸,為什么呢?因為兩匹馬臀部之間的寬度是4英尺8.5英寸,垃圾是放錯位置的人才,世界上最大的悲劇莫過于有太多的年輕人從來沒有發現自己真正想做什么,中小型企業或許能夠讓你得到更充分的鍛煉,從基層做起并不意味著可以從基層的每一個職位做起,要“錢途”,更要前途。
??
??十七、寫字樓政治:白領必修課
??大公司是做人,小公司是做事,職員能否得到提升,很大程度不在于是否努力,而在于老板對你的賞識程度,公司的事情和秘密永遠比你想象的還要復雜和深奧,在適當的時候裝糊涂不但是必要的,而且是睿智的,就把你的同事當成一群你可以叫得出名字的陌生人好了。
??
??十八、創業:29歲以前做富翁
??瘦死的駱駝比馬大,撐死膽大的,餓死膽小的,不再是“大魚吃小魚”,而是“快魚吃慢魚”,對于趨勢的把握是一個創業者最重要的能力,高科技行業留給畢業生的空間已經很小,欲速則不達。在創業以前通過給別人打工而積累經驗是非常必要的,市場永遠比產品更重要,錢不夠花,怎么辦?第一,看菜吃飯;第二,借雞生蛋。
posted @
2006-05-19 15:30 崛起的程序員 閱讀(202) |
評論 (0) |
編輯 收藏
關于李煜
??? 李煜(937-978),初名從嘉,字重光,號鐘隱,又號鐘峰白蓮居士,即位后改名煜。南唐中主第六子。徐州人。宋建隆二年(961年)在金陵即位,在位十五年,世稱李后主。他嗣位的時候,南唐已奉宋正朔,茍安于江南一隅。宋開寶七年(974年),宋太祖屢次遣人詔其北上,均辭不去。同年十月,宋兵南下攻金陵。明年十一月城破,后主肉袒出降,被俘到汴京,封違命侯。太宗即位,進封隴西郡公。太平興國三年(978)七夕是他四十二歲生日,宋太宗恨他 有“故國不堪回首月明中”之詞,命人在宴會上下牽機藥將他毒死。追封吳王,葬洛陽邙山。 后主前期詞作風格綺麗柔靡,還不脫“花間”習氣。國亡后在“日夕只以眼淚洗面”的軟禁生涯中,以一首首泣盡以血的絕唱,使亡國之君成為千古詞壇的“南面王”(清沈雄《古今詞話》語),正是“國家不幸詩家幸, 話到滄桑語始工”。這些后期詞作,凄涼悲壯,意境深遠,已為蘇辛所謂的 “豪放”派打下了伏筆,為詞史上承前啟后的大宗師,如王國維《人間詞話 》所言:“詞至李后主而眼界始大,感慨遂深。”至于其語句的清麗,音韻 的和諧,更是空前絕后的了。 后主本有集,已失傳。現存詞四十四首,其中幾首前期作品或為他人所作,可以確定者僅三十八首。
??? 李煜李煜是多才多藝身,又是多福多苦命。
??? 說他是多才多藝身,是因為他工書善畫,能詩擅詞,又精通音樂。他玩什么,都能玩出名堂。他的書法,自成一家,創造出了“聚針釘”、“金錯刀”、“撮襟”等體式。他作畫,“遠過常流,高出意外”(郭若虛《圖畫見聞志》)。他創作的樂曲,也很“奇絕”,亡國前創作的《念家山》、《念家山破》等樂曲,流行很廣,“宮中民間日夜奏之,未及兩月,傳滿江南”(邵思《雁門野說》”。他還會點武藝,像李璟,弧矢箭術都不賴。多才多藝、精通音律的李煜,寫起小詞來,自然是駕輕就熟。他能創造出《虞美人》之類的絕妙好詞,一點也不奇怪。
??? 說他多福,首先是因為他原本無緣也無心做世子、當國主,卻一不小心,當上了世子,做上了國主。他是李璟的第六子,當世子、做國主原本沒有他的份兒。可憨人有憨福。他的長兄弘冀早就被立為世子,可弘冀莫名其妙地暴死,其他四位兄長又都早夭,這樣李煜就成了“老大”,于是在建隆二年(961),順利地被立為世子。同年,李璟病逝,李煜在金陵登上國主的寶,擁有了至高無上的地位。
??? 后主登基的時候,宋太祖趙匡胤已建言了宋王朝,統一了北方。只是大宋要一個個地收拾其他小國,一時還顧不上平定南唐。于是李后主有李會茍延殘喘,做了十五年的小國之君。宋太祖曾說:“臥榻之下,豈容他人酣睡。”李煜居然在宋太祖的臥榻之下,小心翼翼地睡了十五年。這也算是有福氣吧。
??? 他的福氣,還不止這些。事業、愛情都美滿,才是真正圓滿的人生、幸福的人生。李煜的愛情,也挺幸福的。先后兩個王后,都是天姿國色,而且多才多藝,跟他又情投意合。大周后,小字娥皇,精通書史,善解間律,特別擅長演奏琵琶。既會譜曲,又能填詞,可惜沒有詞作流傳下來。她還是一位時裝和發型設計師,曾設計“高髻纖裳及首翹鬃朵之妝”,人人仿效。有這樣一位可人兒作伴侶,叫后主片不心滿意足?小周后,是娥皇的妹妹,也是“警敏有才思,神彩端靜”,風情萬種。后主與小周后婚前的愛情,更具有刺激性,更令他心蕩神怡。如果說大周后要是引發了后主對音樂的興趣愛好,間接促進了后主詞的創作,那么小周后與后主婚前的頻頻幽會,則是直接為后主的詞作提供了素材。后主詞中的“刬襪步香階,手提金縷鞋”,就是寫與小周后的戀愛經歷。
菩薩蠻
花明月黯籠輕霧,今霄好向郎邊去!
刬襪步香階,手提金縷鞋。
畫堂南畔見,一向偎人顫。
奴為出來難,教君恣意憐。
??? 李后主算不上好國主,卻是一個優秀的詞人,有著藝術家的天真和坦誠。身為國主,連自己的戀愛故事也不隱瞞,公開寫到詞里讓人傳唱,這是多么坦率多情!也許是他覺得這場戀愛太愜意太美滿,以致于情不自禁,跟情人約會之后就把約會的情景用詞記錄下來,作為刻骨鉻心的永恒紀念。
??? 據馬令《南唐書》記載,在大周后病重期間,后主就與她的小妹相戀。娥皇死后,后主娶她小妹為繼室,世稱小周后。這首詞就是寫他與小周后婚前的一次約會。
??? 詞以第一人稱的口吻,讓小周后自述約會的過程,表現她的多情與主動。后主真誠坦率之中,也有狹義獪的一面。他不說自己相約對方,而是說她如何主動大膽。在這場不太合乎當時倫理規范的戀愛中,他似乎是被動的。當然,他們愛得非常意愿。名人的戀愛故事本來就吸引人,風流帝王的戀愛故事更有魅力。這首詞的魅力,倒不僅僅是因為名人效應,藝術上也相當成功。幾個細節和動作,就把人物寫得活靈活現。手提繡鞋,刬襪潛來,見出女子的謹慎心細,生怕被別人發現。“偎人顫”,傳神地寫出她與情郎見面時既緊張又驚喜的神態。詞是專門抒情的詩體,但有些詞抒情時隱含著故事,或者說是因事言情,在講故事時表達情思。詞中這種因事言情的物法,韋莊是最先使用的。他的《荷葉杯》上片回憶當年與情人約會的故事:“記得那年花下。深夜。初識謝娘時。水堂西面畫簾垂。攜手暗相期。”把約會的時間、地點、過程交代得一清二楚。詞中這類故事到底是講詞人的經歷,還是別人的事情,雖然很難判斷,但總有一種逼真感、現場感。這種像是親身經歷的感情故事更能引起讀者聽眾的興趣。到了宋代,歐陽修和柳永的詞也常常使用這種手法,在濃濃的情思中隱含著模糊的故事。
浪淘沙
往事只堪哀,對景難排。
秋風庭院蘚侵階。
一任珠簾閑不卷,終日誰來?
金劍已沉埋,壯氣蒿萊。
晚涼天凈月華開。
想得玉樓瑤殿影,空照秦淮!
??? 此詞為入宋后抒寫幽閉時心情。
?? “往事只堪哀”,是說想起往事就悲哀,而不是說想起悲哀的往事。后主被俘入宋后,總是難忘故國的“往事”。《虞美人》詞說“往事知多少”;《菩薩蠻》詞說“往事已成空”,可見他的“往事”是指過去歡樂“往事”。如今觸目皆悲,所以想起歡樂的往事,更倍增傷感。開篇流露的是幸福的失落感,接下來表現的是沉重的孤獨感。庭院長滿了苔蘚,可見環境的極度荒涼冷清。室內也是死氣沉沉。珠簾不卷,既是無人卷,也是無心卷簾。戶外荒涼,觸目腸斷,不如呆在室內消磨時光。可長期龜縮幽閉一室,內心的孤獨還是不能排解。他在期盼人來,期盼著與人交流、傾訴,可等待“終日”,不見人來,也無人敢來。據宋人王铚《默記》記載,后主在汴京開封的住處,每天都有“一老卒守門”,并“有旨不得與外人接”。李煜在汴京,實質是被軟禁的囚徒。他明明知道沒有人愿意來看望,也沒有人敢來看望,卻偏偏說“終日”有“誰來 ”。他是在失望中期盼,在期盼中絕望。這就是李后主的心態。
??? 在極度孤獨中度日的李煜,打發時光、排遣苦悶的最好方式是回憶往事。金劍沉埋于廢墟,壯氣消沉于荒草,復國的機會與可能是一點兒也沒有了,只好任命吧!就這樣過一天算一天吧!
??? 上片寫的是白天,下片寫晚上,晚涼天靜,月華普照,全詞的境界閃出一絲亮色,主人公的心情也為之開朗。可這月亮已非故鄉之月,就像建安時期王粲《登樓賦》所說的“雖信美而吾土”。于是他由月亮想到當年月光照耀下的秦淮河畔的故國宮殿。但玉樓瑤殿已非我有,明月照得再亮,也只能徒增傷感。后主總是這么執著地留戀過去,故國成了他解不開的情結。故國情結是他后期詞作的一大主題,也是他打發孤獨寂寞時光的一副強心劑。但故國情結并不能解脫心中的屈辱與痛苦。他靠回憶過去打發時光。可是一旦從過去的往事中回到現實,又痛苦不堪。這樣周而復始,后主深深地陷入了無法解開的心理怪圈。
??? 由王子、君主到臣虜,李后主的人生經歷了巨大的反差。正如唐圭璋在《李后主》評傳》中所說:“他身為國王,富貴繁華到了極點,而身經亡國,繁華消竭,不堪回首,悲哀也到了極點。正因為他經歷過這種極端的悲樂,遂使他在文學上的收成也格外光榮而偉大。在歡樂的詞里,我們看見一朵朵美麗之花;在悲哀的詞里,我們看見一縷縷的血痕淚痕。”
??? 然而富貴繁華也好,悲哀血淚也好,這些都違背了李煜的本愿。他的最初理想是做一個遠離塵寰逍遙山林的隱逸之士。在《即位上宋太祖表》中,李后主說的很明白:臣本于諸子,實愧非才。自出膠庠,心疏利祿。……思追巢、許之余塵,遠慕夷、齊之高義。意思是說:當君主并不符合自己本來的志愿。自己的理想只是追步巢父、許由的后塵,做一個像伯夷、叔齊式的隱士。他為自己取了許多別號,自稱“鐘山隱士”、“鐘鋒隱者”、“鐘鋒隱居”、“蓮峰居士”,省稱曰“鐘隱”。可知他心神向往的,完完全全是超越塵俗的山林生活啊!
??? 正是:林花謝了春紅, 太匆匆。無奈朝來寒雨,晚來風!
posted @
2006-05-19 15:23 崛起的程序員 閱讀(197) |
評論 (0) |
編輯 收藏