簡(jiǎn)單的總結(jié)下Java?spi機(jī)制的思想。
SPI的全名為Service Provider Interface.普通開(kāi)發(fā)人員可能不熟悉卧土,因?yàn)檫@個(gè)是針對(duì)廠商或者插件的志鹃。在java.util.ServiceLoader的文檔里有比較詳細(xì)的介紹健田。究其思想娄昆,其實(shí)是和"Callback"差不多佩微。“Callback”的思想是在我們調(diào)用API的時(shí)候萌焰,我們可以自己寫(xiě)一段邏輯代碼哺眯,傳入到API里面,API內(nèi)部在合適的時(shí)候會(huì)調(diào)用它杆怕,從而實(shí)現(xiàn)某種程度的“定制”。
我們系統(tǒng)里抽象的各個(gè)模塊壳贪,往往有很多不同的實(shí)現(xiàn)方案陵珍,比如日志模塊的方案,xml解析模塊违施、jdbc模塊的方案等互纯。面向的對(duì)象的設(shè)計(jì)里,我們一般推薦模塊之間基于接口編程磕蒲,模塊之間不對(duì)實(shí)現(xiàn)類進(jìn)行硬編碼留潦。一旦代碼里涉及具體的實(shí)現(xiàn)類,就違反了可拔插的原則辣往,如果需要替換一種實(shí)現(xiàn)兔院,就需要修改代碼。
為了實(shí)現(xiàn)在模塊裝配的時(shí)候能不在程序里動(dòng)態(tài)指明站削,這就需要一種服務(wù)發(fā)現(xiàn)機(jī)制坊萝。java spi就是提供這樣的一個(gè)機(jī)制:為某個(gè)接口尋找服務(wù)實(shí)現(xiàn)的機(jī)制。有點(diǎn)類似IOC的思想许起,就是將裝配的控制權(quán)移到程序之外十偶,在模塊化設(shè)計(jì)中這個(gè)機(jī)制尤其重要。
當(dāng)服務(wù)的提供者园细,提供了服務(wù)接口的一種實(shí)現(xiàn)之后惦积,在jar包的META-INF/services/目錄里同時(shí)創(chuàng)建一個(gè)以服務(wù)接口命名的文件。該文件里就是實(shí)現(xiàn)該服務(wù)接口的具體實(shí)現(xiàn)類猛频。而當(dāng)外部程序裝配這個(gè)模塊的時(shí)候狮崩,就能通過(guò)該jar包META-INF/services/里的配置文件找到具體的實(shí)現(xiàn)類名蛛勉,并裝載實(shí)例化,完成模塊的注入厉亏。?
基于這樣一個(gè)約定就能很好的找到服務(wù)接口的實(shí)現(xiàn)類董习,而不需要再代碼里制定。
jdk提供服務(wù)實(shí)現(xiàn)查找的一個(gè)工具類:java.util.ServiceLoader
1.common-logging
apache最早提供的日志的門面接口爱只。只有接口皿淋,沒(méi)有實(shí)現(xiàn)。具體方案由各提供商實(shí)現(xiàn)恬试,發(fā)現(xiàn)日志提供商是通過(guò)掃描META-INF/services/org.apache.commons.logging.LogFactory配置文件窝趣,通過(guò)讀取該文件的內(nèi)容找到日志提工商實(shí)現(xiàn)類。只要我們的日志實(shí)現(xiàn)里包含了這個(gè)文件训柴,并在文件里制定LogFactory工廠接口的實(shí)現(xiàn)類即可哑舒。
2.jdbc
jdbc4.0以前,開(kāi)發(fā)人員還需要基于Class.forName("xxx")的方式來(lái)裝載驅(qū)動(dòng)幻馁,jdbc4也基于spi的機(jī)制來(lái)發(fā)現(xiàn)驅(qū)動(dòng)提供商了洗鸵,可以通過(guò)META-INF/services/java.sql.Driver文件里指定實(shí)現(xiàn)類的方式來(lái)暴露驅(qū)動(dòng)提供者。
典型的是Collections.sort(List<T> list,Comparator<? super T> c)這個(gè)方法仗嗦,它的第二個(gè)參數(shù)是一個(gè)實(shí)現(xiàn)Comparator接口的實(shí)例膘滨。我們可以根據(jù)自己的排序規(guī)則寫(xiě)一個(gè)類,實(shí)現(xiàn)此接口稀拐,傳入此方法火邓,那么這個(gè)方法就會(huì)根據(jù)我們的規(guī)則對(duì)list進(jìn)行排序。
把這個(gè)思想擴(kuò)展開(kāi)來(lái)德撬,我們用SPI來(lái)重新實(shí)現(xiàn)上面的例子铲咨。客戶把自己的排序規(guī)則寫(xiě)成一個(gè)類蜓洪,并且打包成Jar文件纤勒,這個(gè)Jar文件里面必須有META-INF目錄,其下又有services目錄隆檀,其下有一個(gè)文本文件踊东,文件名即為接口的全名:
java.util.Comparator
[java]view plaincopy
--META-INF??
????--services??
????--java.util.Comparator??
文件內(nèi)容只有一行:
[java]view plaincopy
com.company1.ComparatorProvider??
這一行是你實(shí)現(xiàn)了Comparator接口的類的全名,它的代碼如下:
[java]view plaincopy
package?com.company1;??
import?java.util.Comparator;??
import?com.mycompany.myapp.MyItem;??
public?class?ComparatorProvider?implements?Comparator<MyItem>{??
@Override??
public?int?compare(MyItem?o1,?MyItem?o2)?{??
//依據(jù)name排序????
return?o1.getName().compareTo(o2.getName());??
????????}??
????}??
編譯打包后刚操,把它放到你的主程序的class path里闸翅。下面是你的主程序:
[java]view plaincopy
//從class?path中所有Jar的META-INF目錄中搜索,找到合適的類并加載菊霜。??
private?static?ServiceLoader<Comparator>?serviceLoader??
=?ServiceLoader.load(Comparator.class);??
public?static?void?main(String[]?args)??
????{??
List?myList?=new?ArrayList<MyItem>();??
myList.add(new?MyItem(2,"c","hhh"));??
myList.add(new?MyItem(3,"k","ooo"));??
myList.add(new?MyItem(4,"d","ppp"));??
myList.add(new?MyItem(5,"b","ggg"));??
????????showList(myList);??
????????Collections.sort(myList,getCompartor());??
????????showList(myList);??????
????}??
@SuppressWarnings("unchecked")??
private?static?Comparator<MyItem>?getCompartor()?{??
for(Comparator?service?:?serviceLoader)??
????????{??
return?(Comparator<MyItem>)service;??
????????}??
return?null;??
????}??
? ? 要注意的是serviceLoader開(kāi)始只是加載類坚冀,實(shí)例化要到第一次用的時(shí)候。類MyItem和方法showList并不重要鉴逞,所以你不必在意记某。你可以按照這個(gè)規(guī)則司训,寫(xiě)另外一個(gè)排序規(guī)則的Jar,隨時(shí)可以更換你的排序規(guī)則.
這篇文章寫(xiě)在我研究J2SE、J2EE近三年后液南。前3年我研究了J2SE的Swing壳猜、Applet、Net滑凉、RMI统扳、Collections、 IO畅姊、JNI……研究了J2EE的JDBC咒钟、Sevlet、JSP若未、JNDI…..不久我發(fā)現(xiàn)這些好像太浮淺了:首先朱嘴,我發(fā)現(xiàn)自己知道的僅僅是java提 供的大量的API,根本不能很好地使用它; 其次粗合,我根本就沒(méi)有學(xué)到任何有助于寫(xiě)程序的知識(shí)萍嬉,此時(shí)我也只不過(guò)能寫(xiě)個(gè)幾頁(yè)的小程序。出于這個(gè)幼稚的想法我研究了JDK中Collections隙疚、 Logger壤追、IO…..的源代碼,發(fā)現(xiàn)這個(gè)世界真的很神奇甚淡,竟然有如此的高手――利用java語(yǔ)言最最基本的語(yǔ)法大诸,創(chuàng)造了這些優(yōu)秀的 Framework捅厂。
從此一發(fā)不可收拾贯卦,我繼續(xù)研究了J2EE的部分,又發(fā)現(xiàn)這是一個(gè)我根本不能理解的方向(曾經(jīng)有半年停滯不前)焙贷,為什么只有接口沒(méi)有實(shí)現(xiàn)啊!后來(lái)由于 一直使用Tomcat撵割、Derby等軟件突然發(fā)現(xiàn):哦!原來(lái)J2EE僅僅是一個(gè)標(biāo)準(zhǔn),只是一個(gè)架構(gòu)辙芍。真正的實(shí)現(xiàn)是不同提供商提供的啡彬。
接著我研究了MOM4J、OpenJMS故硅、Mocki庶灿、HSQLD……發(fā)現(xiàn)這些就是J2EE的實(shí)現(xiàn)啊!原來(lái)軟件竟會(huì)如此復(fù)雜,竟會(huì)如此做….規(guī)范和 實(shí)現(xiàn)又是如何成為一體的呢?通過(guò)上面的研究發(fā)現(xiàn):原來(lái)J2EE后面竟然有太多太多理念吃衅、太多太多的相似!這些相似就是其背后的理念――設(shè)計(jì)模式!(很幸 運(yùn)往踢,在我學(xué)java的時(shí)候,我一般學(xué)java的一個(gè)方向就會(huì)讀一些關(guān)于設(shè)計(jì)模式的書(shū)!很幸運(yùn)徘层,到能領(lǐng)略一點(diǎn)的時(shí)候能真正知道這是為什么!)其實(shí)模式就是一 種思維方式峻呕、就是一種理念……模式是要運(yùn)用到程序中的利职,只有從真正的項(xiàng)目中才能領(lǐng)會(huì)模式的含義……
學(xué)得越多,發(fā)現(xiàn)懂得越少!在學(xué)習(xí)過(guò)程中發(fā)現(xiàn)一些很有用瘦癌,很值得學(xué)習(xí)的開(kāi)源項(xiàng)目猪贪,今天在此推薦給大家。
一讯私、JavaServlet和JSP方向
很多人都是從Servlet和JSP步入J2EE的热押。它就是J2EE的表現(xiàn)層,用于向客戶呈現(xiàn)服務(wù)器上的內(nèi)容妄帘。J2EE很重要的方面楞黄。不羅嗦了!大 家都知道的!下面就開(kāi)始推薦吧!
1. Jakarta Tomcat
Apache基金會(huì)提供的免費(fèi)的開(kāi)源的Serlvet容器,它是的Jakarta項(xiàng)目中的一個(gè)核心項(xiàng)目抡驼,由Apache鬼廓、Sun和其它一些公司(都 是IT界的大鱷哦)及個(gè)人共同開(kāi)發(fā)而成,全世界絕大部分Servlet和Jsp的容器都是使用它哦!由于Sun的參與和支持致盟,最新的Servlet和 Jsp規(guī)范總能在Tomcat中得到體現(xiàn)碎税。
不過(guò)它是一個(gè)非常非常全的Serlvet容器,全部源碼可能有4000頁(yè)馏锡,對(duì)于初學(xué)者或者一般的老手可能還是比較大了!在你有能力時(shí)推薦研究!下載 地址:http://jakarta.apache.org/tomcat/index.html
下面推薦兩個(gè)小一點(diǎn)的吧!
2. Jetty
Jetty是一個(gè)開(kāi)放源碼的HTTP服務(wù)器和Java serverlet容器雷蹂。源代碼只有1000頁(yè)左右,很值得研究杯道。有興趣可以去http://jetty.mortbay.com/下載看看匪煌。我曾經(jīng)翻了 一下,只是目前沒(méi)有時(shí)間党巾。(都化在博客上了萎庭,等博客基本定型,且內(nèi)容完整了齿拂,再干我熱衷的事件吧!)
3. Jigsaw
Jigsaw是W3C開(kāi)發(fā)的HTTP驳规,基于Java 的服務(wù)器,提供了未來(lái) Web 技術(shù)發(fā)展的藍(lán)圖署海。W3C知道吧!(太有名氣了吗购,很多標(biāo)準(zhǔn)都是它制訂的!有空經(jīng)常去看看吧!)下載網(wǎng)址:http://www.w3.org/Jigsaw 代碼僅僅1000頁(yè)左右。
4. Jo!
Jo!是一個(gè)純Java的實(shí)現(xiàn)了Servlet API 2.2, JSP 1.1, 和HTTP/1.1的Web服務(wù)器砸狞。它的特性包括支持servlet tag,支持SSI捻勉,高級(jí)線程管理,虛擬主機(jī)刀森,數(shù)據(jù)緩存踱启,自動(dòng)壓縮text或HTML文件進(jìn)行傳輸,國(guó)際化支持,自動(dòng)重新加載Servlet禽捆、Jsp笙什,自 動(dòng)重新加載web工程文件(WARs),支持WAR熱部署和一個(gè)Swing控制臺(tái)胚想。jo!可以被用做jboss和jakarta avalon-phoenix的web容器琐凭。下載地址http://www.tagtraum.com/ 。我極力推薦大家在研究Tomcat之前研究該軟件浊服,主要是其比Tomcat小多了统屈,且開(kāi)發(fā)者提供比較全的手冊(cè)。該方向研究這兩個(gè)也就可以了!
二牙躺、JDBC方向
很多人都喜歡JDBC愁憔,數(shù)據(jù)庫(kù)嗎!很深?yuàn)W的東西,一聽(tīng)就可以糊弄人孽拷。其實(shí)等你真正研究了數(shù)據(jù)庫(kù)的實(shí)現(xiàn)后發(fā)現(xiàn)吨掌,接口其實(shí)真的太簡(jiǎn)單,太完美了!要想設(shè) 計(jì)如此優(yōu)秀的框架還是需要學(xué)習(xí)的脓恕。下面就推薦幾個(gè)數(shù)據(jù)庫(kù)的實(shí)現(xiàn)吧!
1. Hypersonic SQL
Hypersonic SQL開(kāi)源數(shù)據(jù)庫(kù)方向比較流行的純Java開(kāi)發(fā)的關(guān)系型數(shù)據(jù)庫(kù)膜宋。好像不是JDBC兼容的,JDBC的很多高級(jí)的特性都沒(méi)有支持炼幔,不過(guò)幸好支持ANSI- 92 標(biāo)準(zhǔn) SQL語(yǔ)法秋茫。我推薦它主要是它的代碼比較少1600頁(yè)左右,如此小的數(shù)據(jù)庫(kù)值得研究乃秀,而且他占的空間很小肛著,大約只有160K,擁有快速的數(shù)據(jù)庫(kù)引擎跺讯。推薦 你的第一個(gè)開(kāi)源數(shù)據(jù)庫(kù)枢贿。下載地址:http://hsqldb.sourceforge.NET/。
2. Mckoi DataBase
McKoiDB 和Hypersonic SQL差不多抬吟,它是GPL 的license的純Java開(kāi)發(fā)的數(shù)據(jù)庫(kù)萨咕。他的 JDBC Driver 是使用 JDBC version 3 的 Specifaction统抬。 他也是遵循 SQL-92 的標(biāo)準(zhǔn)火本,也盡量支持新的 SQL 特色, 并且支持 Transaction 的功能。兩個(gè)可以選一個(gè)吧!下載地址:http://mckoi.com/database/聪建。
3. Apache Derby
學(xué)Java的數(shù)據(jù)庫(kù)我建議使用Apache Derby 钙畔,研究數(shù)據(jù)庫(kù)想成為一個(gè)數(shù)據(jù)庫(kù)的高手我建議你先研究Apache Derby。Apache Derby是一個(gè)高質(zhì)量的金麸、純 Java開(kāi)發(fā)的嵌入式關(guān)系數(shù)據(jù)庫(kù)引擎擎析,IBM? 將其捐獻(xiàn)給Apache開(kāi)放源碼社區(qū),同時(shí)IBM的產(chǎn)品CloudSpace是它對(duì)應(yīng)的產(chǎn)品。Derby是基于文件系統(tǒng)揍魂,具有高度的可移植性桨醋,并且是輕量 級(jí)的,這使得它非常便于發(fā)布现斋。主要是沒(méi)有商業(yè)用戶的很好的界面喜最,沒(méi)有其太多的功能。不過(guò)對(duì)于我們使用數(shù)據(jù)庫(kù)庄蹋、研究數(shù)據(jù)庫(kù)還是極其有用的瞬内。對(duì)于中小型的企業(yè) 說(shuō)老實(shí)話你也不要用什么Oracle、SqlServer了限书,用Derby就可以了虫蝶,何況是開(kāi)源的呢!只要能發(fā)揮其長(zhǎng)處也不容易啊!下載地 址:http://incubator.apache.org/derby。
不過(guò)在沒(méi)有足夠的能力前倦西,不要試圖讀懂它!注釋和源代碼15000頁(yè)左右能真,我一年的閱讀量!能讀下來(lái)并且能真正領(lǐng)會(huì)它,絕對(duì)高手!你能讀完 Derby的源代碼只有兩種可能:1.你成為頂尖的高手――至少是數(shù)據(jù)庫(kù)這部分; 2.你瘋了扰柠。選擇吧!!!!作為我自己我先選擇Hypersonic SQL這樣的數(shù)據(jù)庫(kù)先研究舟陆,能過(guò)這一關(guān),再繼續(xù)研究Derby!不就是一年的閱讀量嗎!我可以化3年去研究如何做一個(gè)數(shù)據(jù)庫(kù)其實(shí)還是很值得的!有的人搞 IT一輩子自己什么都沒(méi)有做耻矮,也根本沒(méi)有研究別人的東西!
作為一個(gè)IT落后于別國(guó)若干年的秦躯、從事IT的下游產(chǎn)業(yè)“外包”的國(guó)家的IT從業(yè)人員,我認(rèn)為還是先研究別人的優(yōu)秀的東西比較好!可以先研究別人的裆装, 然后消化踱承,學(xué)為己用!一心閉門造車實(shí)在遺憾!
三、JMS方向
JMS可能對(duì)大家來(lái)說(shuō)是一個(gè)比較陌生的方向!其實(shí)JMS是一個(gè)比較容易理解,容易上手的方向。主要是Java消息服務(wù)蹈集,API也是相當(dāng)簡(jiǎn)單的最岗。不過(guò) 在企業(yè)應(yīng)用中相當(dāng)廣泛。下面就介紹幾個(gè)吧!
1. MOM4J
MOM4J是一個(gè)完全實(shí)現(xiàn)JMS1.1規(guī)范的消息中間件并且向下兼容JMS1.0與1.02贩疙。它提供了自己的消息處理存儲(chǔ)使它獨(dú)立于關(guān)系數(shù)據(jù)與語(yǔ) 言,它的客戶端可以用任何語(yǔ)言開(kāi)發(fā)。它可以算是一個(gè)小麻雀懒熙,很全實(shí)現(xiàn)也比較簡(jiǎn)單!它包含一個(gè)命名服務(wù)器,一個(gè)消息服務(wù)器普办,同時(shí)提供自己的持續(xù)層工扎。設(shè)計(jì)也相 當(dāng)?shù)那擅睿耆?a target="_blank">操作系統(tǒng)中文件系統(tǒng)設(shè)計(jì)的觀念衔蹲。代碼也很少肢娘,250頁(yè)左右,最近我在寫(xiě)該實(shí)現(xiàn)的源代碼閱讀方面的書(shū),希望明年年中能與大家見(jiàn)面!下載地 址:http://mom4j.sourceforge.Net/index.html橱健。
2. OpenJMS
OpenJMS是一個(gè)開(kāi)源的Java Message Service API 1.0.2 規(guī)范的實(shí)現(xiàn)而钞,它包含有以下特性:
1. 它既支持點(diǎn)到點(diǎn)(point-to-point)(PTP)模型和發(fā)布/訂閱(Pub/Sub)模型。
2. 支持同步與異步消息發(fā)送 拘荡。
3. JDBC持久性管理使用數(shù)據(jù)庫(kù)表來(lái)存儲(chǔ)消息 笨忌。
4. 可視化管理界面。
5. Applet支持俱病。
6. 能夠與Jakarta Tomcat這樣的Servlet容器結(jié)合官疲。
7. 支持RMI, TCP, HTTP 與SSL協(xié)議。
8. 客戶端驗(yàn)證 亮隙。
9. 提供可靠消息傳輸途凫、事務(wù)和消息過(guò)濾。
很好的JMS方向的開(kāi)源項(xiàng)目!我目前也在研究它的源代碼!學(xué)習(xí)它可以順便研究JNDI的實(shí)現(xiàn)溢吻、以及網(wǎng)絡(luò)通信的細(xì)節(jié)维费。這是我JMS方向研究的第二個(gè)開(kāi) 源項(xiàng)目。代碼量1600頁(yè)左右吧!下載地址:http://openjms.sourceforge.net/index.html
3. ActiveMQ
ActiveMQ是一個(gè)開(kāi)放源碼基于Apache 2.0 licenced 發(fā)布并實(shí)現(xiàn)了JMS 1.1促王。它能夠與Geronimo犀盟,輕量級(jí)容器和任Java應(yīng)用程序無(wú)縫的給合。主要是Apache的可以任意的使用和發(fā)布哦!個(gè)人比較喜歡Apache 的源代碼!下載地址:http://activemq.codehaus.org/
4. JORAM
JORAM一個(gè)類似于openJMS分布在ObjectWeb之下的JMS消息中間件蝇狼。ObjectWeb的產(chǎn)品也是非常值得研究的!下面我還會(huì)給 大家另外一個(gè)ObjectWeb的產(chǎn)品阅畴。下載地址:http://joram.objectweb.org/
我個(gè)人推薦:OpenJMS和ActiveMQ!
四、EJB方向
EJB一個(gè)比較“高級(jí)”的方向迅耘。Sun公司曾經(jīng)以此在分布式計(jì)算領(lǐng)域重拳出擊贱枣。不過(guò)自從出現(xiàn)了spring、Hibernation……后似乎沒(méi)落 了!這個(gè)方向單獨(dú)開(kāi)源的也比較少颤专,主要EJB是和JNDI纽哥、JDBC、JMS栖秕、JTS春塌、JTA結(jié)合在一起的是以很少有單獨(dú)的。下面推薦兩個(gè)不過(guò)好像也要下 載其它類庫(kù)簇捍。
1. EasyBeans
ObjectWeb的一個(gè)新的項(xiàng)目只壳,一個(gè)輕量級(jí)的EJB3容器,雖然還沒(méi)有正式發(fā)布垦写,但是已經(jīng)可以從它們的subversion倉(cāng)庫(kù)中檢出代碼吕世。代 碼量比較小600頁(yè)左右彰触,熟讀它可以對(duì)網(wǎng)絡(luò)編程梯投、架構(gòu)、RMI、容器的狀態(tài)設(shè)計(jì)比較了解了!即學(xué)會(huì)EJB又能學(xué)習(xí)其它設(shè)計(jì)方法何樂(lè)而不為哦!下載地 址:http://easybeans.objectweb.org/
2. OpenEJB
OpenEJB是一個(gè)預(yù)生成的分蓖、自包含的尔艇、可移植的EJB容器系統(tǒng),可以被插入到任意的服務(wù)器環(huán)境么鹤,包括應(yīng)用程序服務(wù)器终娃,Web服務(wù)器,J2EE平 臺(tái)蒸甜, CORBA ORB和數(shù)據(jù)庫(kù)等等棠耕。OpenEJB 被用于 Apple的WebObjects。聽(tīng)起來(lái)很好柠新,我目前沒(méi)有研究過(guò)窍荧。不知道我就不推薦了。下載地址:http://www.openejb.org/
五恨憎、J2EE容器
上面談了這么多蕊退,都是J2EE的各個(gè)方向的。其實(shí)J2EE是一個(gè)規(guī)范憔恳,J2EE的產(chǎn)品一般要求專業(yè)提供商必須提供它們的實(shí)現(xiàn)瓤荔。這些實(shí)現(xiàn)本身就是 J2EE容器。市場(chǎng)上流行的J2EE容器很多钥组,在開(kāi)源領(lǐng)域流行的只有很少输硝,很少。其中最著名的是JBoss程梦。
1. JBoss
在J2EE應(yīng)用服務(wù)器領(lǐng)域腔丧,Jboss是發(fā)展最為迅速的應(yīng)用服務(wù)器。由于Jboss遵循商業(yè)友好的LGPL授權(quán)分發(fā)作烟,并且由開(kāi)源社區(qū)開(kāi)發(fā)愉粤,這使得 Jboss廣為流行。另外拿撩,Jboss應(yīng)用服務(wù)器還具有許多優(yōu)秀的特質(zhì)衣厘。
其一,它將具有革命性的JMX微內(nèi)核服務(wù)作為其總線結(jié)構(gòu);
其二压恒,它本身就是面向服務(wù)的架構(gòu)(Service-Oriented Architecture影暴,SOA);
其三,它還具有統(tǒng)一的類裝載器探赫,從而能夠?qū)崿F(xiàn)應(yīng)用的熱部署和熱卸載能力型宙。因此,它是高度模塊化的和松耦合的伦吠。Jboss用戶的積極反饋告訴我 們妆兑,Jboss應(yīng)用服務(wù)器是健壯的魂拦、高質(zhì)量的,而且還具有良好的性能搁嗓。為滿足企業(yè)級(jí)市場(chǎng)日益增長(zhǎng)的需求芯勘,Jboss公司從2003年開(kāi)始就推出了 24*7、專業(yè)級(jí)產(chǎn)品支持服務(wù)腺逛。同時(shí)荷愕,為拓展Jboss的企業(yè)級(jí)市場(chǎng),Jboss公司還簽訂了許多渠道合作伙伴棍矛。比如安疗,Jboss公司同HP、 Novell够委、Computer Associates茂契、Unisys等都是合作伙伴。
在2004年6月慨绳,Jboss公司宣布掉冶,Jboss應(yīng)用服務(wù)器通過(guò)了Sun公司的J2EE認(rèn)證。這是Jboss應(yīng)用服務(wù)器發(fā)展史上至今為止最重要的 里程碑脐雪。與此同時(shí)厌小,Jboss一直在緊跟最新的J2EE規(guī)范,而且在某些技術(shù)領(lǐng)域引領(lǐng)J2EE規(guī)范的開(kāi)發(fā)战秋。因此璧亚,無(wú)論在商業(yè)領(lǐng)域,還是在開(kāi)源社 區(qū)脂信,Jboss成為了第一個(gè)通過(guò)J2EE 1.4認(rèn)證的主流應(yīng)用服務(wù)器⊙Ⅲ現(xiàn)在,Jboss應(yīng)用服務(wù)器已經(jīng)真正發(fā)展成具有企業(yè)強(qiáng)度(即狰闪,支持關(guān)鍵級(jí)任務(wù)的應(yīng)用)的應(yīng)用服務(wù)器疯搅。
Jboss 4.0作為J2EE認(rèn)證的重要成果之一,已經(jīng)于2004年9月順利發(fā)布了埋泵。同時(shí)幔欧,Jboss 4.0還提供了Jboss AOP(Aspect-Oriented Programming,面向方面編程)組件丽声。近來(lái)礁蔗,AOP吸引了大量開(kāi)發(fā)者的關(guān)注。它提供的新的編程模式使得用戶能夠?qū)⒎矫?比如雁社,事務(wù))從底層業(yè)務(wù)邏 輯中分離出來(lái)浴井,從而能夠縮短軟件開(kāi)發(fā)周期。用戶能夠單獨(dú)使用Jboss AOP霉撵,即能夠在Jboss應(yīng)用服務(wù)器外部使用它磺浙『槎冢或者,用戶也可以在應(yīng)用服務(wù)器環(huán)境中使用它屠缭。Jboss AOP 1.0已經(jīng)在2004年10月發(fā)布了箍鼓。 很有名吧!可以下載一個(gè)用一下崭参,下載地址:http://www.jboss.org/
關(guān)于JBoss的使用資料也非常多呵曹,甚至比商業(yè)軟件的還多。有機(jī)會(huì)研究吧!
2. JOnAS
JOnAS是一個(gè)開(kāi)放源代碼的J2EE實(shí)現(xiàn)何暮,在ObjectWeb協(xié)會(huì)中開(kāi)發(fā)奄喂。整合了Tomcat或Jetty成為它的Web容器,以確保符合 Servlet 2.3和JSP 1.2規(guī)范海洼。JOnAS服務(wù)器依賴或?qū)崿F(xiàn)以下的Java API:JCA跨新、JDBC、JTA 坏逢、JMS域帐、JMX、JNDI是整、JAAS肖揣、JavaMail 。下載地址:http://jonas.objectweb.org/
3.Apache Geronimo
Apache Geronimo 是 Apache 軟件基金會(huì)的開(kāi)放源碼J2EE服務(wù)器浮入,它集成了眾多先進(jìn)技術(shù)和設(shè)計(jì)理念龙优。 這些技術(shù)和理念大多源自獨(dú)立的項(xiàng)目,配置和部署模型也各不相同事秀。 Geronimo能將這些項(xiàng)目和方法的配置及部署完全整合到一個(gè)統(tǒng)一彤断、易用的模型中。作為符合J2EE標(biāo)準(zhǔn)的服務(wù)器易迹,Geronimo提供了豐富的功能集 和無(wú)責(zé)任 Apache 許可宰衙,具備“立即部署”式J2EE 1.4容器的各種優(yōu)點(diǎn),其中包括:
1. 符合J2EE1.4標(biāo)準(zhǔn)的服務(wù)器 睹欲。
2. 預(yù)集成的開(kāi)放源碼項(xiàng)目 菩浙。
3. 統(tǒng)一的集成模型 。
4. 可伸縮性句伶、可管理性和配置管理功能劲蜻。
我一直比較推薦Apache的產(chǎn)品。主要是可以任意自由地使用考余。下載地址:http://incubator.apache.org /projects/geronimo/
六先嬉、其它
講了這么多大家可能很厭煩了!是不是很多很多啊!其實(shí)不然,我們不會(huì)的太多太多了!不會(huì)的太多太多了楚堤。不管你是不是J2EE高手疫蔓,還是J2SE高 手含懊,有些東西你要絕對(duì)很精明的。例如:1.Java的Collections Framework就是java的數(shù)據(jù)結(jié)構(gòu)了衅胀,不僅要吃透它岔乔,還要能按照需要擴(kuò)展它,利用其思想創(chuàng)建一個(gè)自己的數(shù)據(jù)結(jié)構(gòu)滚躯。2.網(wǎng)絡(luò)編程肯定要會(huì)吧雏门,現(xiàn)在以 及以后很多程序都是不在同一臺(tái)機(jī)器上的,不會(huì)網(wǎng)絡(luò)怎么行哦!3.IO肯定要會(huì)的吧!你的程序難道不用輸入輸出數(shù)據(jù)啊!整個(gè)IO包加NIO也有600多頁(yè)的 源代碼哦!4.JDBC你要會(huì)吧!數(shù)據(jù)庫(kù)都不會(huì)掸掏,在你的企業(yè)應(yīng)用中你的數(shù)據(jù)又保存到哪里啊!文件中――太落后了吧!典型的沒(méi)有學(xué)過(guò)J2EE茁影。盡管數(shù)據(jù)庫(kù)背 后也是采用文件保存的。5.Serverlet丧凤、JSp你要是做網(wǎng)頁(yè)做網(wǎng)站募闲,肯定要做到。問(wèn)你一個(gè)簡(jiǎn)單的問(wèn)題愿待,網(wǎng)頁(yè)中如何實(shí)現(xiàn)分頁(yè)啊!有具體方法的就在本 文章后發(fā)言吧!6. Ant要會(huì)吧!java語(yǔ)言中發(fā)布的工具浩螺,類似與c中的make工具。7.JUnit用過(guò)吧!單元測(cè)試軟件仍侥。你不要啊!你的軟件就沒(méi)有bug!你牛!(建 議大家研究研究其源代碼要出,很有用的框架,包含大量的設(shè)計(jì)模式访圃,源代碼不到100頁(yè)!看了只能感嘆――高手就是高手)細(xì)心的朋友可以看到在你使用的很多 IDE工具中都有JUnit哦!就是它厨幻。
一切的一切才剛剛開(kāi)始!有興趣,有需要你可以研究數(shù)據(jù)庫(kù)連接池的框架腿时,如:C3P0况脆、Jakarta DBCP、 DBPool….可以研究J2EE框架Spring……. Web框架Struts……持久層框架hibernate…..甚至開(kāi)發(fā)工具Eclipse…..Sun領(lǐng)導(dǎo)的點(diǎn)對(duì)點(diǎn)通信的JXTA…..報(bào)表工具 JFreeChart批糟、JasperReports…..分布式網(wǎng)絡(luò)編程的CORBA格了、網(wǎng)絡(luò)通信的JGROUPS、XML解析的xerces…..(在不 經(jīng)意間開(kāi)源已經(jīng)步入你的電腦徽鼎,不信啊!你JDK的安裝目錄jdk1.6.0 src com sun org apache就是Xerces盛末,一個(gè)XML解析的著名的開(kāi)源 項(xiàng)目)
不管怎么樣我還是建議從基本的做起,學(xué)精J2SE否淤,熟讀它的源碼悄但,準(zhǔn)確了解其設(shè)計(jì)理念,然后分頭擊破J2EE――一口吃不成一個(gè)胖子!不要貪多貪 廣!腳踏實(shí)地就可以了!
一石抡、什么是面向接口編程
要正確地使用Java語(yǔ)言進(jìn)行面向?qū)ο蟮木幊涕芟瑥亩岣叱绦虻膹?fù)用性,增加程序的可維護(hù)性啰扛、可擴(kuò)展性嚎京,就必須是面向接口的編程嗡贺。面向接口的編程就意味著:開(kāi)發(fā)系統(tǒng)時(shí),主體構(gòu)架使用接口鞍帝,接口構(gòu)成系統(tǒng)的骨架诫睬。這樣就可以通過(guò)更換實(shí)現(xiàn)接口的類來(lái)更換系統(tǒng)的實(shí)現(xiàn)。
例如:在上節(jié)示例中帕涌,Java接口Introduceable就是系統(tǒng)骨架的一個(gè)重要組成部分摄凡,這個(gè)Java接口定義了一個(gè)方法:detailo中心類和教員類分別實(shí)現(xiàn)了Java接口Introduceable,因此具有了不同的detail方法實(shí)現(xiàn)宵膨。在School2類中架谎,print方法接收的參數(shù)類型是Introduceable炸宵,這樣辟躏,就可以向print方法傳遞任意一個(gè)Introduceable接口的實(shí)現(xiàn)類,在運(yùn)行時(shí)土全,Java虛擬機(jī)會(huì)根據(jù)實(shí)際創(chuàng)建的對(duì)象類型調(diào)用不同的方法實(shí)現(xiàn)捎琐。這就意味著:可以通過(guò)更換實(shí)現(xiàn)接口的類來(lái)更換系統(tǒng)的實(shí)現(xiàn)。
二裹匙、面向接口編程的示例
接下來(lái)通過(guò)一個(gè)示例詳細(xì)講解面向接口編程的實(shí)現(xiàn)過(guò)程瑞凑。
案例需求的效果圖如圖1所示。
升級(jí)系統(tǒng)概页,要求如下:
★ 打印機(jī)有多種類型籽御,比如:黑白打印機(jī)、彩色打印機(jī)等惰匙。
★ 中心可能配備其中任意一款打印機(jī)技掏,負(fù)責(zé)打印教員或者中心的詳細(xì)信息。
★ 系統(tǒng)要具備良好的可擴(kuò)展性與可維護(hù)性项鬼。
圖1 使用不同類型的打印機(jī)進(jìn)行打印
采用面向接口編程的方式實(shí)現(xiàn)可以分為3個(gè)步驟哑梳。
1.抽象出Java接口
分析:由于黑白、彩色打印機(jī)都存在一個(gè)共同的方法特征:print绘盟,而且黑白鸠真、彩色打印機(jī)對(duì)print方法有各自不同的實(shí)現(xiàn),因此可以抽象出一個(gè)Java接口PrinterFace(代表打印機(jī))龄毡,在其中定義print方法吠卷。
具體實(shí)現(xiàn)代碼如下:
[java]view plaincopy
package?Java.sg.ch03;?????
public?interface?PrinterFace?{?????
//定義打印方法?????
public?voicl?print?(String?content);?????
???}????
2.實(shí)現(xiàn)Java接口
分析:在第一步中已經(jīng)抽象出Java接口PrinterFace,并在其中定義了print方法沦零。由于黑白祭隔、彩色打印機(jī)對(duì)print方法有各自不同的實(shí)現(xiàn),因此在第2步中蠢终,要讓黑白序攘、彩色打印機(jī)實(shí)現(xiàn)PrinterFace接口茴她,各自實(shí)現(xiàn)print方法。
彩色打印機(jī)代碼實(shí)現(xiàn)如下:
[java]view plaincopy
package?Java.sg.ch03;?????
public?class?ColorPrinter?implements??????
??????PrinterFace?{?????
/**??
?????????*?打印方法??
?????????*/????
public?void?print(String?content)?{?????
System.out.println("彩色打印??:");?????
?????????????System.out.println(content);?????
????????}?????
?????}
黑白打印機(jī)代碼實(shí)現(xiàn)如下:
[java]view plaincopy
package?Java.sg.ch03;?????
public?class?BlackPrinter?implements??????
?????PrinterFace?{?????
/**??
?????????*?打印方法??
?????????*/????
public?void?print(String?content)?{?????
System.out.println("黑白打印??:");?????
?????????????System.out.println(content);?????
????????}?????
????}??
3.使用Java接口
經(jīng)驗(yàn):現(xiàn)在程奠,Java接口及其實(shí)現(xiàn)類都已經(jīng)創(chuàng)建完畢丈牢,接著,我們就要使用面向接口編程的原則瞄沙,讓接口構(gòu)成系統(tǒng)的骨架己沛,以便達(dá)到更換實(shí)現(xiàn)接口的類就可以更換系統(tǒng)的實(shí)現(xiàn)的目的。
中心類負(fù)責(zé)對(duì)外提供打印功能距境,要求可以隨時(shí)更換打印機(jī)類型申尼。代碼實(shí)現(xiàn)如下:
[java]view plaincopy
package?Java.sg.ch03;?????
public?class?School3?implements?Introduceable{?????
private?PrinterFace?printer;??//打印機(jī)?????
//??輸出中心的詳細(xì)信息?????
public?String?detail()?{?????
return?"這里是中心";?????
??????????}?????
//??使用中心打印機(jī)打印信息?????
public?void?print(Introduceable?intro){?????
??????????????printer.print(intro.detail());?????
??????????}?????
//設(shè)置打印機(jī)?????
public?void?setPrinter(PrinterFace?p)?{?????
this.printer?=?p;?????
??????????}?????
??????}??
測(cè)試類提供main方法進(jìn)行單元測(cè)試。代碼實(shí)現(xiàn)如下:
[java]view plaincopy
package?Java.sg.ch03;?????
public?class?Test?{?????
public?static?void?main(String[]?args)?{?????
//創(chuàng)建中心實(shí)例?????
School3?school?=new?School3();?????
//為該中心配備黑白打印機(jī)?????
school.setPrinter(new?BlackPrinter());?????
??????????school.print(school);??????
//為該中心配備彩色打印機(jī)?????
school.setPrinter(new?ColorPrinter());?????
??????????school.print(school);?????
???????}?????
?????}??
經(jīng)驗(yàn):面向接口編程可以實(shí)現(xiàn)接口和實(shí)現(xiàn)的分離垫桂,這樣做的最大好處就是能夠在客戶端未知的情況下修改實(shí)現(xiàn)代碼师幕。那么什么時(shí)候應(yīng)該抽象出Java接口呢?一種是用在層和層之問(wèn)的調(diào)用诬滩。層和層之間是最忌諱耦合度過(guò)高或是改變過(guò)于頻繁霹粥。設(shè)計(jì)優(yōu)秀的接口能夠解決這個(gè)問(wèn)題。另一種是用在那些不穩(wěn)定的部分上疼鸟。如果某些需求的變化性很大后控,那么定義接口也是一種解決之道。設(shè)計(jì)良好的接口就像是我們?nèi)粘J褂玫娜f(wàn)用插座一樣空镜,不論插頭如何變化浩淘,都可以使用。
最后強(qiáng)調(diào)一點(diǎn)吴攒,良好的接口定義一定是來(lái)自于需求的张抄,它絕對(duì)不是程序員絞盡腦汁想出來(lái)的。