J2EE容器也稱為J2EE服務器,大部分時它們概念是一致的。
http://www.douzhe.com/jerry/archive/archive1_cn.htm
容器:充當中間件的角色
WEB容器:給處于其中的應用程序組件(JSP,SERVLET)提供一個環境,使JSP,SERVLET直接更容器中的環境變量接口交互,不必關注其它系統問題。主要有WEB服務器來實現。例如:TOMCAT,WEBLOGIC,WEBSPHERE等。該容器提供的接口嚴格遵守J2EE規范中的WEB APPLICATION 標準。我們把遵守以上標準的WEB服務器就叫做J2EE中的WEB容器。
EJB容器:Enterprise Java bean 容器。更具有行業領域特色。他提供給運行在其中的組件EJB各種管理功能。只要滿足J2EE規范的EJB放入該容器,馬上就會被容器進行高效率的管理。并且可以通過現成的接口來獲得系統級別的服務。例如郵件服務、事務管理。
WEB容器和EJB容器在原理上是大體相同的,更多的區別是被隔離的外界環境。WEB容器更多的是跟基于HTTP的請求打交道。而EJB容器不是。它是更多的跟數據庫、其它服務打交道。但他們都是把與外界的交互實現從而減輕應用程序的負擔。例如SERVLET不用關心HTTP的細節,直接引用環境變量session,request,response就行、EJB不用關心數據庫連接速度、各種事務控制,直接由容器來完成。
RMI/IIOP:遠程方法調用/internet對象請求中介協議,他們主要用于通過遠程調用服務。例如,遠程有一臺計算機上運行一個程序,它提供股票分析服務,我們可以在本地計算機上實現對其直接調用。當然這是要通過一定的規范才能在異構的系統之間進行通信。RMI是Java特有的。
JNDI:Java命名目錄服務。主要提供的功能是:提供一個目錄系統,讓其它各地的應用程序在其上面留下自己的索引,從而滿足快速查找和定位分布式應用程序的功能。
JMS:Java消息服務。主要實現各個應用程序之間的通訊。包括點對點和廣播。
JavaMAIL:Java郵件服務。提供郵件的存儲、傳輸功能。他是Java編程中實現郵件功能的核心。相當MS中的EXCHANGE開發包。
JTA:Java事務服務。提供各種分布式事務服務。應用程序只需調用其提供的接口即可。
JAF:Java安全認證框架。提供一些安全控制方面的框架。讓開發者通過各種部署和自定義實現自己的個性安全控制策略。
EAI:企業應用集成。是一種概念,從而牽涉到好多技術。J2EE技術是一種很好的集成實現。
EJB容器
EJB容器用來容納業務邏輯,并為業務邏輯截取請求。EJB容器支持EJB訪問JMS、JAAS、JTA、JavaMail、JAXP、JDBC和連接器(Connector)。
Web容器
Web容器截取通過HTTP、FTP、SMTP或其他協議發送的請求。Web應用容器為Servlet和JSP頁面提供的資源與EJB容器提供的資源相同。
應用客戶端容器
客戶端應用是獨立的Java應用,它們在遠程的獨立JVM上運行(與Web容器和EJB容器所運行的JVM不同)。應用客戶端容器為這些應用截取請求。
運行在應用客戶端容器上的程序非常類似于帶有main()方法的Java程序,不過,程序不再由JVM控制,而是由一個容器(也就是應用客戶端容器)控制。
在應用客戶端容器內運行的程序能夠訪問遠程應用服務器上的JAXP、JDBC、JMS和JAAS資源。
Applet容器
Applet容器是一個特殊的容器,它為在瀏覽器內運行的Java程序截取請求。Applet容器不提供任何對其他資源(比如JDBC或JMS)的訪問。在Applet容器內運行的Applet必須自己直接向應用服務器請求資源(而不是把請求發送給容器,然后由容器發送請求給應用服務器)。
對于Applet如何與EJB容器進行通信,EJB規范沒有作出任何規定,但J2EE規范有這方面的規定。對于那些想要直接使用EJB的Applet,J2EE規范要求它們使用HTTP隧道。許多應用服務器提供某種形式的HTTP隧道,支持Applet直接使用EJB。
All about JAXP
http://www-128.ibm.com/developerworks/java/library/x-jaxp
Brett McLaughlin
Document Object Model (DOM)
Simple API for XML (SAX)
JDK1.4
javax.xml.parsers
javax.xml.transform
javax.xml.transform.dom
javax.xml.transform.sax
javax.xml.transform.stream
JDK5.0
javax.xml
javax.xml.datatype
javax.xml.namespace
javax.xml.parsers
javax.xml.transform
javax.xml.transform.dom
javax.xml.transform.sax
javax.xml.transform.stream
javax.xml.validation
javax.xml.xpath
嚴格來說,
JAXP
并沒有提供新的解析
XML
的方法,但是它使得我們更容易地使用
DOM
或者
SAX
來進行解析任務,更能以一種
vendor-neutral
的方式來使用
DOM
和
SAX
。
JAXP
與
SAX, DOM, JDOM
和
dom4j
(這四個都可以解析
XML
)沒有可比較性,它并沒有提供一個新的解析
XML
的方法。
JAXP API, located in the
javax.xml.parsers
package. All of these classes sit on top of an existing parser.
其中的
6
個類都是建立在已有的解析上面的。
JDOM
與
dom4j
都提供不同的模型來接受來自
SAX/DOM
的數據,他們從內部來講都是使用了
SAX
,不過是做了些修改。
此外,
Java 1.5
中
Xerces
的包
org.apache.xerces
被放到了
com.sun.org.apache.xerces.internal
First, com.sun.xml.tree.XMLDocument class is not part of JAXP. It is part of Sun's Crimson parser, packaged in earlier versions of JAXP.
Second, a major purpose of JAXP is to provide vendor independence when dealing with parsers. With JAXP, you can use the same code with Sun's XML parser, Apache's Xerces XML parser, and Oracle's XML parser.
先從
SAX
說起,我們只用繼承
DefaultHandler
類
(org.xml.sax.helpers
包中
)
就能獲得所有的
callbacks
,只用在需要的方法中加入實現的代碼。
Here's the typical SAX routine:
1
.
Create a SAXParser instance using a specific vendor's parser implementation.
2
.
Register callback implementations (by using a class that extends DefaultHandler, for example).
3
.
Start parsing and sit back as your callback implementations are fired off.
SAX
必須
指定
XML
驅動(如
org.apache.xerces.parsers.SAXParser
),而
JAXP
提供了更好的選擇,只要我們提供什么
XML
驅動(在
classpath
中配置),它就調用什么驅動,不需要改動代碼。
new SAXParserFactory.newSAXParser()
就返回
JAXP
SAXParser
類,這個類包裝了
SAX parser (an instance of the SAX class
org.xml.sax.XMLReader
)
。
In Listing 1, you can see that two JAXP-specific problems can occur in using the factory: the inability to obtain or configure a SAX factory, and the inability to configure a SAX parser.
The first of these problems, represented by a FactoryConfigurationError, usually occurs when the parser specified in a JAXP implementation or system property cannot be obtained.
The second problem, represented by a ParserConfigurationException, occurs when a requested feature is not available in the parser being used. Both are easy to deal with and shouldn't pose any difficulty when using JAXP.
SAXParser
的
parse
方法可以接受
SAX InputSource
,
Java InputStream
或者
URL in String form
可以通過
SAXParser
的
getXMLReader()
方法來獲得底層的
SAX parser
(
org.xml.sax.XMLReader
的實例),這樣就可以使用各個
SAXParser
方法。
[
參照
Listing2]
使用
DOM
The only difference between DOM and SAX in this respect is that with DOM you substitute DocumentBuilderFactory for SAXParserFactory, and DocumentBuilder for SAXParser.
The major difference is that variations of the parse() method do not take an instance of the SAX DefaultHandler class. Instead they return a DOM Document instance representing the XML document that was parsed. The only other difference is that two methods are provided for SAX-like functionality:
The
javax.xml.transform.Source
interface is the basis for all input into JAXP and the transformation API. This interface defines only two methods --
getSystemId()
and
setSystemId(String systemId)
.
JAXP
提供了三個實現
Source
接口的類:
javax.xml.transform.dom.DOMSource
passes a DOM
Node
(and its children) into JAXP.
javax.xml.transform.sax.SAXSource
passes the results of SAX callbacks (from an
XMLReader
) into JAXP.
javax.xml.transform.stream.StreamSource
passes XML wrapped in a
File
,
InputStream
, or
Reader
into JAXP.?
?
javax.xml.transform.Result
也有兩個方法:
getSystemId()
和
setSystemId(String systemId)
。
同樣有三個實現類:
javax.xml.transform.dom.DOMResult
passes transformed content into a DOM
Node
.
javax.xml.transform.sax.SAXResult
passes the results of a transformation to a SAX
ContentHandler
.
javax.xml.transform.stream.StreamResult
passes the transformed *ML into a
File
,
OutputStream
, or
Writer
.
JAXP this way has two significant limitations:
Transformer
object processes the XSL stylesheet each and every time
transform()
is executed.
Transformer
are not thread-safe. You can't use the same instances across multiple threads.
Transformer
實例不是線程安全的,不能通過多線程去使用同一個
Transformer
實例。
javax.xml.transform.Templates
.
The
Templates
interface is thread-safe (addressing the second limitation) and represents a compiled stylesheet (addressing the first limitation).
Templates
實例是線程安全的,可以處理一堆
XSL
,解決了上述兩個限制。
如果只要對一個
stylesheet
進行一個
transformation
,那么用
Transformer
比較快,沒有必要選擇
Templates
對象。但是考慮到線程安全問題,還是推薦使用
Templates
。
JAXP
默認使用
Xalan-J
,如果要使用其它
parser
,可以通過
javax.xml.transform.TransformerFactory
修改。
java -D javax.xml.transform.TransformerFactory=[transformer.impl.class] TestTransformations?
simple.xml simple.xsl
?
Document E09
SourceForge.net: Subversion (Version Control for Source Code)
http://sourceforge.net/docman/display_doc.php?docid=31070&group_id=1
Subversion
官方網站,查看
http://subversion.tigris.org/
欣慰的是這里有個網站提供一本免費的、非常棒的
SVN
圖書,可以選擇在線查看或者下載
PDF
,
SVN
使用者必讀。
http://svnbook.red-bean.com/
各個版本控制系統功能比較的文章
http://better-scm.berlios.de/comparison/comparison.html
Subversion
使用手記
中文英文對照
http://robinlet.bokee.com/2866408.html
一篇文章介紹如何將
CVS
的
Repository
轉換成
SNV
轉換方法來自這個程序
http://cvs2svn.tigris.org/
官方的那本書是最好的教程,網上還有大量的安裝和使用的文章可以借鑒,這里簡單羅列幾個
SVN
輔助的軟件:
1
、
SubVersion
,從
http://subversion.tigris.org/
下載,是實現服務系統的軟件,必裝的。
2
、
TortoiseSVN
,從
http://tortoisesvn.tigris.org/
下載,是很不錯的
SVN
客戶端程序,為
windows
外殼程序集成到
windows
資源管理器和文件管理系統的
Subversion
客戶端,用起來很方便。
3
、
SVNService.exe
,從
http://dark.clansoft.dk/~mbn/svnservice/
下載,是專為
SubVersion
開發的一個用來作為
Win32
服務掛接的入口程序。
4
、
AnkhSVN
,從
http://ankhsvn.tigris.org/
下載,這是一個專為
Visual Studio
提供
SVN
的插件。
5
、
Subversive
,從
http://www.polarion.org/p_subversive.php
下載,一個為
Eclipse
提供
SVN
的插件,據說已經和
Eclipse
自帶的
CVS
功能有一拼。
6
、還有很多很多
SVN
相關的工具以及使用
TIP
介紹,大家可以上官方的相關鏈接頁面中查看,地址:
http://subversion.tigris.org/links.html
在
Linux
下有一個功能強大的軟件安裝卸載工具,名為
RPM
。它可以用來建立、安裝、查詢、更新、卸載軟件。該工具是在命令行下使用的。在
Shell
的提示符后輸入
rpm
,就可獲得該命令的幫助信息。
Linux
下軟件的安裝主要有三種不同的形式。
第一種安裝文件名為
xxx.tar.gz
;
第二種安裝文件名為
xxx.i386.rpm
,
還有一種是
xxx.src.rpm
。
以第一種方式發行的軟件多為以源碼形式發送的;
第二種方式則是直接以二進制形式發送的;
第三種是
rpm
格式發布的源碼。
對于第一種
[xxx.tar.gz]
,安裝方法如下:
1 .
首先,將安裝文件拷貝至你的目錄中。例如,如果你是以
root
身份登錄上的,就將軟件拷貝至
/root
中。
#cp xxx.tar.gz /root
2 .
由于該文件是被壓縮并打包的
,
應對其解壓縮。命令為:
#tar xvzf filename.tar.gz
3.
執行該命令后,安裝文件按路徑,解壓縮在當前目錄下。用
ls
命令可以看到解壓縮后的文件。通常在解壓縮后產生的文件中,有
“Install”
的文件。該文件為純文本文件,詳細講述了該軟件包的安裝方法。
4.
執行解壓縮后產生的一個名為
configure
的可執行腳本程序。它是用于檢查系統是否有編譯時所需的庫,以及庫的版本是否滿足編譯的需要等安裝所需要的系統信息。為隨后的編譯工作做準備。命令為:
#./configure
5.
檢查通過后,將生成用于編譯的
MakeFile
文件。此時,可以開始進行編譯了。編譯的過程視軟件的規模和計算機性能的不同,所耗費的時間也不同。命令為:
#make
。
6.
成功編譯后,鍵入如下的命令開始安裝:
#make install
7.
安裝完畢,應清除編譯過程中產生的臨時文件和配置過程中產生的文件。鍵入如下命令:
#make clean
#make distclean
至此,軟件的安裝結束。
對于第二種
[xxx.i386.rpm]
,其安裝方法要簡單得多。
同第一種方式一樣,將安裝文件拷貝至你的目錄中。然后使用
rpm
來安裝該文件。命令如下:
#rpm -i filename.i386.rpm
rpm
將自動將安裝文件解包,并將軟件安裝到缺省的目錄下。并將軟件的安裝信息注冊到
rpm
的數據庫中。參數
i
的作用是使
rpm
進入安裝模式。
軟件的卸載
1.
軟件的卸載主要是使用
rpm
來進行的。卸載軟件首先要知道軟件包在系統中注冊的名稱。鍵入命令:
#rpm -q -a
即可查詢到當前系統中安裝的所有的軟件包。
2.
確定了要卸載的軟件的名稱,就可以開始實際卸載該軟件了。鍵入命令:
#rpm -e [package name]
即可卸載軟件。參數
e
的作用是使
rpm
進入卸載模式。對名為
[package name]
的軟件包進行卸載。由于系統中各個軟件包之間相互有依賴關系。如果因存在依賴關系而不能卸載,
rpm
將給予提示并停止卸載。你可以使用如下的命令來忽略依賴關系,直接開始卸載:
#rpm -e [package name] -nodeps
忽略依賴關系的卸載可能會導致系統中其它的一些軟件無法使用
對于第三種
[xxx.src.rpm]
,安裝也很簡單
拷貝到目標目錄,然后執行
#rpmbuild --rebuild xxx.src.rpm
編譯文件
然后進入
#cd /usr/src/redhat(or other)/RPMS/i386/
執行
#rpm -ivh xxxxx.rpm
安裝
上面的方法是對
Redhat 8.0
以及
Mandrake9.0
來說的,如果是低于這個版本。應該用
#rpm --rebuild *.src.rpm
與
C
或
C++
編寫的程序不同,
Java
程序并不是一個可執行文件,而是由許多獨立的類文件組成,每一個文件對應于一個
Java
類。此外,這些類文件并非立即全部都裝入內存,而是根據程序需要裝入內存。
ClassLoader
是
JVM
中將類裝入內存的那部分。而且,
Java ClassLoader
就是用
Java
語言編寫的。這意味著創建您自己的
ClassLoader
非常容易,不必了解
JVM
的微小細節。
Java
的
classloader
不但可以使你運行本地得
class
類
,
你也可以定制
classloader
運行來自遠程的字節代碼
.
ClassLoader
的基本目標是對類的請求提供服務。當
JVM
需要使用類時,它根據名稱向
ClassLoader
請求這個類,然后
ClassLoader
試圖返回一個表示這個類的
Class
對象。
通過覆蓋對應于這個過程不同階段的方法,可以創建定制的
ClassLoader
。通常當你需要動態加載資源的時候
,
你至少有三個
ClassLoader
可以選擇
:
1.??????
系統類加載器(應用類加載器)
(system classloader or application classloader)
2.??????
當前類加載器
3.??????
當前線程類加載器
第一種
:
系統類加載器
系統類加載器
(system classloader).
這個類加載器處理
-classpath
下的類加載工作
,
可以通過
ClassLoader.getSystemClassLoader()
方法調用
.
ClassLoader
下所有的
getSystemXXX()
的靜態方法都是通過這個方法定義的
.
在你的代碼中
,
你應該盡量少地調用這個方法
,
以其它的類加載器作為代理
.
否則你的代碼將只能工作在簡單的命令行應用中
,
這個時候系統類加載器
(system classloader)
是
JVM
最后創建的類加載器
.
一旦你把代碼移到
EJB, Web
應用或
Java Web Start
應用中
,
一定會出問題
.
Class.loadClass( String name, boolean resolve );
name
參數指定了
JVM
需要的類的名稱,該名稱以包表示法表示,如
Foo
或
? java.lang.Object
。
resolve
參數告訴方法是否需要解析類。在準備執行類之前,應考慮類解析。并不總是需要解析。如果
JVM
只需要知道該類是否存在或找出該類的超類,那么就不需要解析。
方法
defineClass
是
ClassLoader
的主要訣竅。
該方法接受由原始字節組成的數組并把它轉換成
Class
對象。原始數組包含如從文件系統或網絡裝入的數據。
defineClass
管理
JVM
的許多復雜、神秘和倚賴于實現的方面
--
它把字節碼分析成運行時數據結構、校驗有效性等等。不必擔心,您無需親自編寫它。事實上,即使您想要這么做也不能覆蓋它,因為它已被標記成最終的。
方法
findSystemClass
findSystemClass
方法從本地文件系統裝入文件。它在本地文件系統中尋找類文件,如果存在,就使用
defineClass
將原始字節轉換成
Class
對象,以將該文件轉換成類。當運行
Java
應用程序時,這是
JVM
正常裝入類的缺省機制
.
??
如果
ClassLoader
不能找到類,它會請求父代
ClassLoader
來執行此項任務。所有
ClassLoaders
的根是系統
ClassLoader
,它會以缺省方式裝入類
--
即,從本地文件系統。
方法
findLoadedClass
充當一個緩存
當請求
loadClass
裝入類時,它調用該方法來查看
ClassLoader
是否已裝入這個類,這樣可以避免重新裝入已存在類所造成的麻煩。應首先調用該方法。
讓我們看一下如何組裝所有方法。
loadClass
實現示例執行以下步驟:
(這里,我們沒有指定生成類文件是采用了哪種技術,它可以是從
Net
上裝入、或者從歸檔文件中提取、或者實時編譯。無論是哪一種,那是種特殊的神奇方式,使我們獲得了原始類文件字節。)
1.??
調用
findLoadedClass
來查看是否存在已裝入的類。
2.??
如果沒有,那么采用那種特殊的神奇方式來獲取原始字節。
3.??
如果已有原始字節,調用
defineClass
將它們轉換成
Class
對象。
4.??
如果沒有原始字節,然后調用
findSystemClass
查看是否從本地文件系統獲取類。
5.??
如果
resolve
參數是
true
,那么調用
resolveClass
解析
Class
對象。
6.??
如果還沒有類,返回
ClassNotFoundException
。
7.??
否則,將類返回給調用程序。
第二種選擇
:
當前上下文環境下的類加載器
.
| |||||||||
日 | 一 | 二 | 三 | 四 | 五 | 六 | |||
---|---|---|---|---|---|---|---|---|---|
30 | 31 | 1 | 2 | 3 | 4 | 5 | |||
6 | 7 | 8 | 9 | 10 | 11 | 12 | |||
13 | 14 | 15 | 16 | 17 | 18 | 19 | |||
20 | 21 | 22 | 23 | 24 | 25 | 26 | |||
27 | 28 | 29 | 30 | 31 | 1 | 2 | |||
3 | 4 | 5 | 6 | 7 | 8 | 9 |