java控制臺輸出由print( ) 和 println( )來完成最為簡單。這兩種方法由rintStream(System.out引用的對象類型)定義。盡管System.out是一個字節(jié)流,用它作為簡單程序的輸出是可行的。因為PrintStream是從OutputStream派生的輸出流,它同樣實現低級方法write(),write()可用來向控制臺寫數據。PrintStream 定義的write( )的最簡單的形式如下:
成都創(chuàng)新互聯(lián)公司一直在為企業(yè)提供服務,多年的磨煉,使我們在創(chuàng)意設計,成都全網營銷到技術研發(fā)擁有了開發(fā)經驗。我們擅長傾聽企業(yè)需求,挖掘用戶對產品需求服務價值,為企業(yè)制作有用的創(chuàng)意設計體驗。核心團隊擁有超過10年以上行業(yè)經驗,涵蓋創(chuàng)意,策化,開發(fā)等專業(yè)領域,公司涉及領域有基礎互聯(lián)網服務西部信息服務器租用、手機APP定制開發(fā)、手機移動建站、網頁設計、網絡整合營銷。
void write(int byteval)
該方法按照byteval指定的數目向文件寫字節(jié)。盡管byteval 定義成整數,但只有低位的8個字節(jié)被寫入。下面的短例用 write()向屏幕輸出字符“A”,然后是新的行。
// Demonstrate System.out.write().
class WriteDemo {
public static void main(String args[]) {
int b;
b = 'A';
System.out.write(b);
System.out.write('\n');
}
}
一般不常用write()來完成向控制臺的輸出(盡管這樣做在某些場合非常有用),因為print()和println() 更容易用。
四、PrintWriter類
盡管Java允許用System.out向控制臺寫數據,但建議僅用在調試程序時或在例程中。對于實際的程序,Java推薦的向控制臺寫數據的方法是用PrintWriter流。PrintWriter是基于字符的類。用基于字符類向控制臺寫數據使程序更為國際化。PrintWriter定義了多個構造函數,這里所用到的一個如下:
PrintWriter(OutputStream outputStream, boolean flushOnNewline)
outputStream是OutputStream類的對象,flushOnNewline控制Java是否在println()方法被調用時刷新輸出流。如果flushOnNewline為true,刷新自動發(fā)生,若為false,則不發(fā)生。
PrintWriter支持所有類型(包括Object)的print( )和println( )方法,這樣,就可以像用ystem.out那樣用這些方法。如果遇到不同類型的情況,PrintWriter方法調用對象的toString()方法并打印結果。用PrintWriter向外設寫數據,指定輸出流為System.out并在每一新行后刷新流。例如這行代碼創(chuàng)建了與控制臺輸出相連的PrintWriter類。
PrintWriter pw = new PrintWriter(System.out, true);
下面的應用程序說明了用PrintWriter處理控制臺輸出的方法:
// Demonstrate PrintWriter
import java.io.*;
public class PrintWriterDemo {
public static void main(String args[]) {
PrintWriter pw = new PrintWriter(System.out, true);
pw.println("This is a string");
int i = -7;
pw.println(i);
double d = 4.5e-7;
pw.println(d);
}
}
該程序的輸出如下:
This is a string
-7
4.5E-7
io包支持Java的基本I/O(輸入/輸出)系統(tǒng),包括文件的輸入/輸出。對輸入/輸出的支持是來源于Java的內核API庫,而不是語言關鍵字。
一、輸入/輸出基礎
很多實際的Java應用程序不是基于文本的控制臺程序。盡管基于文本的程序作為教學實例是很出色的,它們無法勝任JAVA在實際中的重要應用。Java對外設輸入/輸出的支持也是有限的,并且用起來有些笨拙——甚至是在簡單的例子程序中?;谖谋镜目刂婆_輸入/輸出對于Java程序并不是十分重要。
Java 提供了與文件和網絡相關的強大的和靈活的輸入/輸出支持,Java的輸入/輸出系統(tǒng)是緊密相連并且是具有一致性的。
1.1 流的概念
Java程序通過流來完成輸入/輸出。流是生產或消費信息的抽象。流通過Java的輸入/輸出系統(tǒng)與物理設備鏈接。盡管與它們鏈接的物理設備不盡相同,所有流的行為具有同樣的方式。這樣,相同的輸入/輸出類和方法適用于所有類型的外部設備。這意味著一個輸入流能夠抽象多種不同類型的輸入:從磁盤文件,從鍵盤或從網絡套接字。同樣,一個輸出流可以輸出到控制臺,磁盤文件或相連的網絡。流是處理輸入/輸出的一個潔凈的方法,例如它不需要代碼理解鍵盤和網絡的不同。Java中流的實現是在java.io包定義的類層次結構內部的。
1.2 字節(jié)流和字符流
要使用流類,必須導入Java.io包。Java 2 定義了兩種類型的流:字節(jié)類和字符類。字節(jié)流(byte stream)為處理字節(jié)的輸入和輸出提供了方便的方法。例如使用字節(jié)流讀取或書寫二進制數據。字符流(character stream)為字符的輸入和輸出處理提供了方便。它們采用了統(tǒng)一的編碼標準,因而可以國際化。在某些場合,字符流比字節(jié)流更有效。在最底層,所有的輸入/輸出都是字節(jié)形式的?;谧址牧髦粸樘幚碜址峁┓奖阌行У姆椒?。下面是對字節(jié)流和字符流的概述。
1.2.1 字節(jié)流類
字節(jié)流由兩個類層次結構定義。在頂層有兩個抽象類:InputStream 和 OutputStream。每個抽象類都有多個具體的子類,這些子類對不同的外設進行處理,例如磁盤文件,網絡連接,甚至是內存緩沖區(qū)。字節(jié)流類顯示于表1-1中。
表1-1 字節(jié)流類
流類 含義
BufferedInputStream緩沖輸入流
BufferedOutputStream緩沖輸出流
ByteArrayInputStream從字節(jié)數組讀取的輸入流
ByteArrayOutputStream向字節(jié)數組寫入的輸出流
DataInputStream包含讀取Java標準數據類型方法的輸入流
DataOutputStream包含編寫Java標準數據類型方法的輸出流
FileInputStream讀取文件的輸入流
FileOutputStream寫文件的輸出流
FilterInputStream實現InputStream
FilterOutputStream實現OutputStream
InputStream描述流輸入的抽象類
OutputStream描述流輸出的抽象類
PipedInputStream輸入管道
PipedOutputStream輸出管道
PrintStream包含print()和println()的輸出流
PushbackInputStream 支持向輸入流返回一個字節(jié)的單字節(jié)的“unget”的輸入流
RandomAccessFile支持隨機文件輸入/輸出
SequenceInputStream兩個或兩個以上順序讀取的輸入流組成的輸入流
抽象類InputStream 和 OutputStream定義了實現其他流類的關鍵方法。最重要的兩種方法是read()和write(),它們分別對數據的字節(jié)進行讀寫。兩種方法都在InputStream 和OutputStream中被定義為抽象方法。它們被派生的流類重載。
1.2.2 字符流類
字符流類由兩個類層次結構定義。頂層有兩個抽象類:Reader和Writer。這些抽象類處理統(tǒng)一編碼的字符流。Java中這些類含有多個具體的子類。字符流類如表1-2所示。
表1-2 字符流的輸入/輸出類
抽象類Reader和Writer定義了幾個實現其他流類的關鍵方法。其中兩個最重要的是read()和write(),它們分別進行字符數據的讀和寫。這些方法被派生流類重載。
1.3 預定義流
所有的Java程序自動導入java.lang包。該包定義了一個名為System的類,該類封裝了運行時環(huán)境的多個方面。System 同時包含三個預定義的流變量,in,out和err。這些成員在System中是被定義成public 和static型的,這意味著它們可以不引用特定的System對象而被用于程序的其他部分。
System.out是標準的輸出流。默認情況下,它是一個控制臺。System.in是標準輸入,默認情況下,它指的是鍵盤。System.err指的是標準錯誤流,它默認是控制臺。然而,這些流可以重定向到任何兼容的輸入/輸出設備。System.in 是inputStream的對象;System.out和System.err是PrintStream的對象。它們都是字節(jié)流,盡管它們用來讀寫外設的字符。但可以用基于字符的流來包裝它們。
二、讀取控制臺輸入
在Java 1.0中,完成控制臺輸入的惟一途徑是字節(jié)流,使用該方法的老代碼依然存在。今天,運用字節(jié)流讀取控制臺輸入在技術上仍是可行的,但這樣做需要用到不被贊成的方法,這種做法不值得推薦。Java 2中讀取控制臺輸入的首選方法是字符流,它使程序容易符合國際標準并且易于維護。
Java沒有像標準C的函數scanf()或C++輸入操作符那樣的統(tǒng)一的控制臺輸入方法。Java中,控制臺輸入由從System.in讀取數據來完成。為獲得屬于控制臺的字符流,在BufferedReader對象中包裝System.in。BufferedReader 支持緩沖輸入流查看批注。它最常見的構造函數如下:
BufferedReader(Reader inputReader)
這里,inputReader是鏈接被創(chuàng)建的BufferedReader實例的流。Reader是一個抽象類。它的一個具體的子類是InputStreamReader,該子類把字節(jié)轉換成字符查看批注。為獲得鏈接System.in的一個InputStreamReader的對象,用下面的構造函數:
InputStreamReader(InputStream inputStream)
因為System .in引用了InputStream 類型的對象,它可以用于inputStream。綜上所述,下面的一行代碼創(chuàng)建了與鍵盤相連的BufferedReader對象。
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
當該語句執(zhí)行后,br是通過System.in生成的鏈接控制臺的字符流。
2.1 讀取字符
從BufferedReader讀取字符,用read()。這里所用的read()版本如下:
int read( ) throws IOException
該方法每次執(zhí)行都從輸入流讀取一個字符然后以整型返回。當遇到流的末尾時它返回-1。可以看到,它要引發(fā)一個IOException異常。下面的例程演示了read()方法,從控制臺讀取字符直到用戶鍵入“q”:
// Use a BufferedReader to read characters from the console.
import java.io.*;
class BRRead {
public static void main(String args[])
throws IOException
{
char c;
BufferedReader br = new
BufferedReader(new InputStreamReader(System.in));
System.out.println("Enter characters, 'q' to quit.");
// read characters
do {
c = (char) br.read();
System.out.println(c);
} while(c != 'q');
}
}
下面是程序運行:
Enter characters, 'q' to quit.
123abcq
1
2
3
a
b
c
q
2.2 讀取字符串
從鍵盤讀取字符串,使用readLine()。它是BufferedReader 類的成員。它的通常形式如下:
String readLine( ) throws IOException
它返回一個String對象。下面的例子闡述了BufferedReader類和readLine()方法;程序讀取和顯示文本的行直到鍵入“stop”:
// Read a string from console using a BufferedReader.
import java.io.*;
class BRReadLines {
public static void main(String args[])
throws IOException
{
// create a BufferedReader using System.in
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
String str;
System.out.println("Enter lines of text.");
System.out.println("Enter 'stop' to quit.");
do {
str = br.readLine();
System.out.println(str);
} while(!str.equals("stop"));
}
}
下面的例程生成了一個小文本編輯器。它創(chuàng)建了一個String對象的數組,然后依行讀取文本,把文本每一行存入數組。它將讀取到100行或直到按“stop”才停止。該例運用一個BufferedReader類來從控制臺讀取數據。
// A tiny editor.
import java.io.*;
class TinyEdit {
public static void main(String args[])
throws IOException
{
// create a BufferedReader using System.in
BufferedReader br = new BufferedReader(new
InputStreamReader(System.in));
String str[] = new String[100];
System.out.println("Enter lines of text.");
System.out.println("Enter 'stop' to quit.");
for(int i=0; i100; i++) {
str[i] = br.readLine();
if(str[i].equals("stop")) break;
}
System.out.println("\nHere is your file:");
// display the lines
for(int i=0; i100; i++) {
if(str[i].equals("stop")) break;
System.out.println(str[i]);
}
}
}
下面是輸出部分:
Enter lines of text.
Enter ‘stop’ to quit.
This is line one.
This is line two.
Java makes working with strings easy.
Just create String objects.
stop
Here is your file:
This is line one.
This is line two.
Java makes working with strings easy.
Just create String objects.
操作簡單,要求硬件配置低。
量級主要是看容器的依賴性所決定的,依賴性越小,越輕量,
Jim Rivera是 BEA 公司的一位技術主管,負責通過技術傳播推廣BEA 產品的應用。Jim 于1999 年加入BEA,擔任 BEA WebLogic Server 6、7 和8 版本的技術產品經理。在這個崗位上,Jim 負責各種服務器組件的策略和路線圖,包括 EJB、Web services、XML 和集群。Jim 在dev2dev 上有一個blog。dev2dev 通過電子郵件采訪了 Jim,獲得他對輕量級Java、應用程序框架和持久性框架,以及它們與應用服務器上企業(yè)計算的關系的看法。
輕量級Java
dev2dev: 您是如何定義“輕量級Java”的?
Jim: 我認為,在Java 應用程序開發(fā)環(huán)境中,“輕量級Java”主要是指兩個東西:簡化的編程模型和更具響應能力的容器。輕量級Java 旨在消除與傳統(tǒng) J2EE API 有關的不必要的復雜性和限制。它也將縮短應用程序的部署時間,這對于支持開發(fā)最佳實踐(比如頻繁單元測試)非常重要。
dev2dev: 對您來說哪種輕量級技術是最重要的,輕量級Java 對終端用戶有什么幫助?
Jim: 很顯然,控制反轉 (IoC)模式在這個領域有著重大的影響。使用IoC,開發(fā)人員不需要編寫復雜的代碼來執(zhí)行查詢、處理基礎架構異?;蚬芾磉B接,就能夠解決對象依賴性問題。這有助于簡化代碼、將業(yè)務邏輯與基礎架構分離,從而使應用程序更易于維護。
輕量級Java 的另一個關鍵特征是,它不會強迫業(yè)務對象遵循平臺特定接口。這允許開發(fā)人員在普通舊式Java 對象(POJO)中實現業(yè)務邏輯,從而提高生產率。
與具體的類相反,當把開發(fā)的最佳實踐與界面相結合時,這些特性也使得對代碼進行單元測試容易得多。由于業(yè)務邏輯實現在 POJO中,所以不再需要將對象部署到重量級容器中以在單元測試中練習它。因此,將對象宿主在諸如 JUnit 之類的簡單測試環(huán)境中和為快速迭代單元測試“模擬”外部依賴性就變得微不足道了。
dev2dev: 作為一個技術傳播者,您一定目睹了許多新的和已部署的技術。您是否看到了轉向輕量級技術的趨勢?
Jim: 當然。在早期的采用者當中,明確地存在轉向諸如 Spring、Hibernate 和Beehive 之類框架的趨勢。它在應用程序的構建方式上有了明顯的不同,對未來 J2EE技術的方向有著積極的影響。例如,EJB 3.0就基本上是以使得輕量級Java盛行的概念為基礎的。
重量級
dev2dev:人們在想起應用服務器供應商時,通常把它們置于“重量級陣營”。我想您正在努力改變這種狀況,對吧?換言之,許多人認為應用程序供應商已經在實現重量級組件(比如 EJB 2.0)上付出了很大的代價,它們不愿意輕易放棄這些成果。
Jim: 首先,我認為沒有理由放棄在 EJB 上的現有投資,因為在某些場景中它仍然是最好的技術,例如當您希望通過 RMI遠程公開業(yè)務服務時。當然,諸如 EJB 之類的開放標準在保護客戶投資方面的價值也不能低估。
已經說過,我覺得人們經常過分強調 EJB在應用服務器中的實際價值。盡管這一點未必對所有的應用服務器供應商都適用,但是 BEA 只投入了相對較少的一部分開發(fā)資源來支持 J2EE API。我們工作最主要的目標是為宿主應用程序構建最可靠、可伸縮和容錯的內核。這些品質以及分布式事務服務、高速消息傳遞、遺留系統(tǒng)集成、高級 Web 服務、配置管理、診斷和故障排除和高級安全性,代表了 WebLogic Server 的真正價值,而且對總體擁有成本(TCO)有著巨大的影響。幸運的是,這些附加值對基于Spring 或Beehive 的應用程序的相關性和適用性與采用EJB 構建的應用程序是一樣的。雖然輕量級Java 技術使得應用程序的開發(fā)和維護更容易,但是它們不會代替真正高端應用服務器的品質。實際上,我們認為輕量級Java 與WebLogic Server 是一致的。
dev2dev: BEA 有沒有一個輕量級 Java 策略?BEA 實現輕量級 Java 的方法是什么?
Jim: 我們的策略是接納所有有利于提高開發(fā)人員生產率、在市場上為部署這些技術提供最佳平臺的技術。輕量級 Java有助于降低開發(fā)成本,WebLogic Server 則有助于降低運營成本,它們是一個非常強大的組合。
應用程序框架
dev2dev:由BEA贊助的Beehive項目顯然是一個輕量級 Java組件模型。您能否談談關于 Beehive 的情況,以及它在你們的整個策略中的地位?
Jim: Beehive是一個應用程序框架,致力于使J2EE 應用程序和基于SOA 的應用程序的開發(fā)更容易,它基于我們發(fā)布WebLogic Workshop 的經驗。它基于 POJO 和用于配置依賴性、服務質量等的元數據提供一個編程模型。元數據以 J2SE 5.0 代碼注解和外部 XML文件的形式獲得支持。存在一些用于訪問 J2EE資源、定義業(yè)務和 Web 服務以及基于 MVC模式開發(fā) Web 應用程序的組件。在我們努力提高開發(fā)人員生產率、鞏固 Java 整體市場的過程中,Beehive 是非常關鍵的一部分。
dev2dev: Beehive 可以被認為是一個“應用程序框架”。在Spring Framework中提供了一種非常流行的輕量級 Java 方法。Spring(以及其他類似的框架)對于 BEA 有多重要?
Jim: 任何能夠幫助我們的客戶提高生產率的東西都對我們非常重要。我們歡迎并且接納這些技術,在適當的時候也可以在技術層面上集成或者共享這些技術。
dev2dev: 你們考慮過明確支持這些框架嗎?
Jim: 就像我原來說過的,WebLogic Server具有很多方面的特性,能夠提供基于輕量級 Java 技術的應用程序。許多都是隱含的,然而在某些情況下,最小量的集成工作就能為輕量級 Java 開發(fā)人員提供重要的價值。舉個例子,當今存在的一些適配器允許 Spring 應用程序使用 WebLogic Server 的分布式事務能力,無需改變任何應用程序代碼。我們正在調查許多其他的機會,當然也一直在傾聽客戶的需求。
dev2dev: 我們已經看到輕量級框架對EJB 3 的一些影響。您認為這會擴展到J2EE的其他方面嗎?
Jim: 是的。我認為 JSR 175(即Java元數據)對于簡化 J2EE 編程模型是一種關鍵的支持技術。EJB 3.0使用了它,而且它也是 JSR 181(即Web Services 元數據,一個BEA 倡導的規(guī)范)的基礎。沒有理由相信它會就此停止。
輕量級持久性
dev2dev: IoC 容器看起來是輕量級 Java 的中心。另外的一個關鍵因素是POJO 和輕量級持久性。您能針對這個問題談談看法嗎?
Jim: 同樣,共同的主題是簡化編程模型。沒有比POJO更簡單的了。當然,企業(yè)開發(fā)要求我們有能力應用附加的品質,比如持久性規(guī)則、事務語義和 POJO 的安全約束。盛行很廣的方式是在元數據中定義這些品質,要么作為代碼注解,要么放在外部文件中。
dev2dev: 您是否覺得因為有多種方法用于完成持久性這樣的事情而存在一些危險?比如,我們很快將會有EJB 2、EJB 3、JDO、Hibernate,等等。
Jim: 我認為這只是成熟領域的一個實際情況。多年來,J2EE 規(guī)范沒有完全涵蓋這個特定的領域,自然就會導致其他規(guī)范的出現。就我所知道的在 JCP中發(fā)生的事情,我們似乎正在走向統(tǒng)一。這對于整個行業(yè)來說是一件好事。
未來
dev2dev: 您能預見一下輕量級 Java和 BEA 的未來嗎?
Jim: 我們將會繼續(xù)活躍于這個領域中,既通過諸如 Apache Beehive、XMLBeans、Eclipse和JCP 之類的渠道推動創(chuàng)新,又吸收諸如 Spring 這樣的其他領先技術,并且為了客戶的利益而展開協(xié)作。
艾伯特.愛因斯坦曾經說過:“一切都應該盡可能地簡單,但是不能更簡單?!贝_實如此,簡化一門理論的基本假設,使我們可以專注于真正關鍵的地方,這正是一直以來對科學真理的追求。企業(yè)軟件開發(fā)同樣如此。
提供一個將復雜的事物(例如,事務、安全或持久性)對開發(fā)者進行隱藏的應用框架是簡化企業(yè)軟件開發(fā)的關鍵。一個設計良好的框架可以提高代碼重用率、開發(fā)者的生產力及軟件的質量。然而,現有J2EE1.4的EJB2.1框架被普遍認為設計差,且過于復雜。不滿于EJB2.1的框架結構,Java開發(fā)者嘗試了各種各樣的中間件服務傳遞方法。最引人注目的是,以下兩個框架引起了開發(fā)者極大興趣并得到了大量正面的反饋。他們以未來企業(yè)Java應用所選框架的姿態(tài)展現。
Spring框架雖然很流行但并不是一個標準的開源框架。它主要由Interface21 Inc開發(fā)和控制。Spring框架結構是基于依賴注入(Dependency Injection (DI))的設計模式。它可以獨立或在現有的應用服務器上運行,而且大量地使用了xml配置文件
EJB3.0是由Java Community Process (JCP)制訂的標準框架,為所有主要的J2EE廠商支持。JBoss已經提供了試用版EJB3.0標準的開源或商業(yè)性質實現。EJB3.0充分利用了Java的注釋
這兩個框架結構都有一個共同核心設計理念:將中間件服務傳遞給耦合松散的POJOS (Plain Old Java Objects, 簡單潔凈Java對象)。 這樣的框架利用截取執(zhí)行上下文或在運行時將服務對象注入POJO來把應用服務“纏繞”到POJO。POJO本身并不關心這種“纏繞”,對這種框架結構也沒有什么依賴。因此,開發(fā)者可專注于業(yè)務邏輯和脫離框架的POJO單元測試。除此之外, 由于POJO并不須要繼承框架的類或實現其接口,開發(fā)者能夠極其靈活地搭建繼承結構和建造應用。
然而,在擁有同一理念的同時,兩個框架結構使用不同的方式來傳遞POJO服務。許多書籍或文章都將Spring 或EJB3.0和EJB2.1做了比較,但是對Spring 和EJB3.0的比較并沒有仔細研究過。在本文中,我將對Srping和EJB3.0框架背后的關鍵不同處進行考察,并討論其優(yōu)缺點。本文的觀點也適用于其它更少為人知的框架,因為他們都是對“耦合松散的POJO”的設計。希望這篇文章可以幫助你選擇適合你需求的最好框架。
廠商無關性
開發(fā)者選擇Java平臺其中最引人注目的理由之一:廠商無關性。EJB3.0正是一套設計為廠商無關的開放性標準。EJB3.0標準為所有企業(yè)Java社團里開源或商業(yè)性質廠商所開發(fā)和支持。它將開發(fā)者與應用服務器實現完全隔離。例如,JBoss的 EJB3.0實現基于Hibernate,Oracle的基于TopLink,但是開發(fā)者并不須要學習Hibernate- 或TopLink的具體API來使應用可在Jboss或Oracle上運行。廠商無關性使EJB3.0與現今其它POJO中間件框架區(qū)別開來。
但是,正如許多EJB3.0評論家迅速所指出的,在本文撰寫時EJB3.0標準還沒有到達一個最終版本。大概還有一到兩年的時間EJB3.0才能廣泛地為所有主要J2EE廠商所支持。即使你的應用服務器本身不支持EJB3.0,你仍然可以通過下載安裝”內嵌的”EJB3.0產品來運行EJB3.0的應用。例如,JBoss的內嵌EjB3.0是開源產品且可以在任何J2SE5.0兼容的環(huán)境運行(例如, 在任何Java服務器上),此產品正處于軟件測試階段。其它廠商不久也將發(fā)布自己的內嵌EJB3.0產品,特別是針對標準中關于數據持久性的部分。
另一方面,Spring一直以來都是非標準的技術,在未來可預知的一段時間內這種情況將持續(xù)下去。雖然你可以在任何應用服務器上使用Spring框架,Spring應用會被鎖入在Spring本身和你選擇整合進Spring的具體服務中。
Spring框架是一個開源項目,但同時它有一個XML格式的配置文件和編程接口。當然任何一個非標準的產品都會有這種“鎖入”(lock-in)的情況,并不是Spring特有的。但Spring應用的長期生存能力仍然還得托Spring這個項目的福(或者是Interface21公司,它雇傭了大部分Spring核心開發(fā)人員)。除此之外,假如你用到任何一個具體的Spring服務,例如,Spring事務管理器或則Spring MVC,你也會被鎖入到這些API里。
Spring的應用對終端用戶是不可知的。例如,對數據持久服務,Spring框架兼容不同的DAO和JDBC的模版幫助類,如Hibernate, iBatis, 和 JDO。所以假如你需要為spring應用切換在數據持久化服務(例如從JBDC到Hibernate),你需要修改你的代碼以適合新的模版幫助類。
服務整合
從一個很高的角度上看,Spring框架處于應用服務器和服務庫的上方。服務整合的代碼(如,數據訪問模板和幫助類)屬于框架,并暴露于應用開發(fā)者。相反,EJB3.0框架與應用服務器高度整合,服務整合代碼也包裝在一個標準接口后面。
因此,實現EJB3.0的廠商可以大大地優(yōu)化整體性能和提升開發(fā)者的體驗。例如,在JBoss EJB3.0的實現中,當你在用EntityManager持久化一個Entity Bean時,后臺的Hibernate會話事務已經自動地幫定到調用方法的JTA 的事務上,在JTA 事務提交的同時Hibernate會話事務也提交了。你甚至可以使用一個簡單的 @PersistenceContext 注釋(稍候例子演示)將EntityManager和它后臺的Hibernate事務綁定到一個stateful session bean的應用事務中。在一個會話中應用事務橫跨多個線程,這在事務性網頁應用很有用,例如,多頁面的購物車。
由于高度整合的EJB3.0的框架,使簡單、集成的編程接口成為可能。Oracle EJB3.0框架和其后臺的Toplink持久化服務也同樣程度地整合。
另一個EJB3.0整合服務的絕好例子就是集群支持。假如你在一個服務器集群上部署了一個EJB3.0的應用,所有容錯(fail-over)、負載均衡、分布式緩沖和狀態(tài)復制都已經自動為應用所獲得可用。后臺的集群支持被隱藏在EJB3.0的框架后面,對EJB3.0開發(fā)者來說這些都是完全透明不可見的。
在Spring里,很難優(yōu)化框架和服務之間的通訊。例如,為了使用Spring里的聲明事務服務來管理Hibernate事務,你必須顯示地在XML文件中配置Spring TransactionManager和Hibernate SessionFactory對象。Spring必須電顯示地管理橫跨多個HTTP請求的事務。除此之外,沒有別的方法均衡Spring應用里的集群。
服務組合的彈性
由于Spring的服務整合代碼作為編程接口的一部份暴露在外,應用開發(fā)者有按自己需求裝配服務的彈性。這個特點使你能夠組合自己的輕量級應用服務器。Spring的一個普遍用法就是將Tomcat和Hibernate組合在一起支持數據庫驅動的web應用。在這種情況,Spring本身提供事務服務,Hibernat提供持久化服務——這種設置創(chuàng)建了一個袖珍型的應用服務器。
EJB3.0應用服務器典型地不提供這種根據需求任你挑撿服務的彈性空間。大多數時間,你得到的只是一系列包裝好的特性,其中一些你可能根本就不需要。但是如果應用服務器像JBoss一樣提供一個模塊性的內部設計,那么你可以只取其中一部分,而把不必要的部分剝去。在任何情況,去自定義一個功能強大的應用服務器是沒有什么價值的。
當然,假如應用已經超過單個點,那么你應該加入常用服務器上的服務,例如,資源池(resource pooling),消息隊列(message queuing)和集群(clustering)。就總體的資源消耗而言,Spring解決方法和其他EJB3.0解決方法一樣是重量級的。
在Spring框架里,具有彈性的服務裝配使得將虛擬對象而不是真正的業(yè)務對象綁定到應用中做脫離容器的單元測試更簡單。在EJB3.0應用中,大多數組件都是簡單POJO,他們可以很容易地在容器外被測試。但是對于與容器服務相關的對象(例如持久化實實體管理器EntityManager)建議用容器內測試。因為這樣會比虛擬對象測試方法更簡單,強壯及準確。
XML Vs.注解
從應用開發(fā)者的觀點上來看,Spring的編程開發(fā)接口主要基于XML配置文件而EJB3.0廣泛地應用Java注解。XML可以表達復雜的關系,但是它也冗長且不夠健壯;注解簡單明了,但是很難在注解里表達復雜或繼承性的關系。
Spring選擇XML或EJB3.0選擇注解都是有他們兩者框架后的體系結構決定的。因為注解只能容納很少的配置信息,只有整合前的框架(重頭戲都在框架里)才可以把廣泛地使用注解作為配置選擇。正如我們所討論過的,EJB3.0剛好符合這個要求,而Spring作為一個普通的DI框架并不符合。
當然,EJB3.0和Spring都相互取長補短,在某種程度上他們都支持XML和注解。例如,在EJB3.0中,XML配置文件作為一個可選的重載機制來改變注解的默認行為。注解也可以配置一些Spring服務。
通過例子是學習XML和注解方式之間差異的最好方法。在下面幾個環(huán)節(jié)里,讓我們來看看Spring和EJB3.0是怎樣提供關鍵服務給應用的。
聲明性服務
Spring和EJB3.0都將運行時服務(例如,事務、安全、日志和配置服務)綁定到應用。因為這些服務于應用的業(yè)務邏輯是沒有直接聯(lián)系,他們只是由應用本身管理。換句話說,這些服務在運行時由容器透明地應用到應用中。開發(fā)者或是管理者配置容器,準確地告訴它什么時候怎樣應用這些服務。
EJB3.0運用Java注解來配置聲明性服務,而Sring使用XML配置文件。在大多數情況下,EJB3.0注解方式對于這種服務更簡單明了。這里有一個在EJB3.0中將事務服務運用到POJO的例子。
public class Foo }
你也可以為一個代碼段聲明多個屬性,應用多個服務。這是一個在EJB3.0里同時應用事務和安全服務到POJO的例子
1.下載JAVA程序,電腦上下載的JAVA分兩種,1.rar壓縮包,rar壓縮包解壓后包含2個文件:JAR和JAD .2.JAR壓縮包。rar壓縮包比較簡單解壓就可以了,至于JAR就要生成JAD文件了,怎么生成呢!下載JAD生成器,迅雷搜一下一大把,懶得下或下不到的就到“手機樂園“在線生成(網址就不發(fā)了,百度搜索下)。
2.把JAR和JAD文件一起傳入手機內存卡,方法 4種,1數據線,2讀卡器,3藍牙,4紅外線。常用的是1和2,3和4我家電腦不支持我不懂,講下數據線,三星手機要連接USB要下載安裝PC套件,沒有的買個碟子安裝或網上下載,有讀卡器的就讀卡器,把下載好了的JAR和JAD文件通過USB傳到手機內存卡 Other files文件夾里,沒有的就建一個。傳好后就把卡放回手機。
3.啟動JAVA安裝,待機狀態(tài)下輸入*#9998*4678255# .手機顯示已啟動即可。
4.進入手機內存卡的“Other files”夾里,選中JAD后按選項,手機提示是否安裝,選擇OK .
5.安裝完的游戲自動儲存在JAVA世界 .其他文件夾中的JAR和JAD即可刪除了.留著也行以備不小心刪了軟件可以重新安裝。
安裝方法就是這樣的,根據多次安裝失敗經歷,把安裝JAVA失敗的狀況做了一下總結:
1.一定要用英文字符或數字為JAR和JAD文件命名,而且命名長度不要太長,越短越好。如果用中文字符起名的話可是安不進去文件的.
2.JAVA程序的JAR文件大小,不要超過手機所限制的大小,否則也是安裝不了.
3.如果前2個條件都滿足,安裝JAVA還是發(fā)生錯誤,則只保留JAR文件,刪除JAD文件.下載JAD生成器重新生成jad文件,再安裝試試.
4.還有一些安裝時候容易搞錯的地方,JAR和JAD文件記得一定是傳入手機內存卡的"Other files",待機狀態(tài)下輸入指令的時候,手機會提示"已啟動",這時候是開啟JAVA安裝,再次輸入指令,提示"未啟動",JAVA安裝也就關閉了.
5.如果條件滿足以上所述,還安裝不起JAVA,就是手機不支持該JAVA程序了.