??xml version="1.0" encoding="utf-8" standalone="yes"?>极品美乳网红视频免费在线观看,青青操视频在线,亚洲成在线观看http://www.aygfsteel.com/chenlb/category/17116.html好记性不如烂W头!zh-cnMon, 17 Mar 2008 14:31:23 GMTMon, 17 Mar 2008 14:31:23 GMT60必读Q彻底明白Java的IOpȝ---JAVA之精髓IO! http://www.aygfsteel.com/chenlb/articles/186758.html浪?/dc:creator>浪?/author>Mon, 17 Mar 2008 06:26:00 GMThttp://www.aygfsteel.com/chenlb/articles/186758.htmlhttp://www.aygfsteel.com/chenlb/comments/186758.htmlhttp://www.aygfsteel.com/chenlb/articles/186758.html#Feedback0http://www.aygfsteel.com/chenlb/comments/commentRss/186758.htmlhttp://www.aygfsteel.com/chenlb/services/trackbacks/186758.htmlhttp://www.cnblogs.com/wjun530/archive/2007/06/14/782898.html

d明白Java的IOpȝ

一Q?Input和Output
1. stream代表的是M有能力出数据的数据源,或是M有能力接收数据的接收源。在Java的IO中,所有的streamQ包括Input和Out streamQ都包括两种cdQ?br /> 1.1 以字节ؓ导向的stream
以字节ؓ导向的streamQ表CZ字节为单位从stream中读取或往stream中写入信息。以字节为导向的stream包括下面几种cdQ?br /> 1) input streamQ?br /> 1) ByteArrayInputStreamQ把内存中的一个缓冲区作ؓInputStream使用
2) StringBufferInputStreamQ把一个String对象作ؓInputStream
3) FileInputStreamQ把一个文件作为InputStreamQ实现对文g的读取操?br /> 4) PipedInputStreamQ实Cpipe的概念,主要在线E中使用
5) SequenceInputStreamQ把多个InputStream合ƈZ个InputStream
2) Out stream
1) ByteArrayOutputStreamQ把信息存入内存中的一个缓冲区?br /> 2) FileOutputStreamQ把信息存入文g?br /> 3) PipedOutputStreamQ实Cpipe的概念,主要在线E中使用
4) SequenceOutputStreamQ把多个OutStream合ƈZ个OutStream
1.2 以Unicode字符为导向的stream
以Unicode字符为导向的streamQ表CZUnicode字符为单位从stream中读取或往stream中写入信息。以Unicode字符为导向的stream包括下面几种cdQ?br /> 1) Input Stream
1) CharArrayReaderQ与ByteArrayInputStream对应
2) StringReaderQ与StringBufferInputStream对应
3) FileReaderQ与FileInputStream对应
4) PipedReaderQ与PipedInputStream对应
2) Out Stream
1) CharArrayWriteQ与ByteArrayOutputStream对应
2) StringWriteQ无与之对应的以字节为导向的stream
3) FileWriteQ与FileOutputStream对应
4) PipedWriteQ与PipedOutputStream对应
以字Wؓ导向的stream基本上对有与之相对应的以字节为导向的stream。两个对应类实现的功能相同,字是在操作时的导向不同。如CharArrayReaderQ和ByteArrayInputStream的作用都是把内存中的一个缓冲区作ؓInputStream使用Q所不同的是前者每ơ从内存中读取一个字节的信息Q而后者每ơ从内存中读取一个字W?br /> 1.3 两种不现导向的stream之间的{?br /> InputStreamReader和OutputStreamReaderQ把一个以字节为导向的stream转换成一个以字符为导向的stream?br /> 2. streamd属?br /> 2.1 “为streamd属?#8221;的作?br /> q用上面介绍的Java中操作IO的APIQ我们就可完成我们想完成的Q何操作了。但通过FilterInputStream和FilterOutStream的子c,我们可以为streamd属性。下面以一个例子来说明q种功能的作用?br /> 如果我们要往一个文件中写入数据Q我们可以这h作:
FileOutStream fs = new FileOutStream(“test.txt”);
然后可以通过产生的fs对象调用write()函数来往test.txt文g中写入数据了。但是,如果我们惛_?#8220;先把要写入文件的数据先缓存到内存中,再把~存中的数据写入文g?#8221;的功能时Q上面的API没有一个能满我们的需求了。但是通过FilterInputStream和FilterOutStream的子c,为FileOutStreamd我们所需要的功能?br /> 2.2 FilterInputStream的各U类?br /> 2.2.1 用于装以字节ؓ导向的InputStream
1) DataInputStreamQ从stream中读取基本类型(int、char{)数据?br /> 2) BufferedInputStreamQ用缓冲区
3) LineNumberInputStreamQ会记录input stream内的行数Q然后可以调用getLineNumber()和setLineNumber(int)
4) PushbackInputStreamQ很用刎ͼ一般用于编译器开?br /> 2.2.2 用于装以字Wؓ导向的InputStream
1) 没有与DataInputStream对应的类。除非在要用readLine()时改用BufferedReaderQ否则用DataInputStream
2) BufferedReaderQ与BufferedInputStream对应
3) LineNumberReaderQ与LineNumberInputStream对应
4) PushBackReaderQ与PushbackInputStream对应
2.3 FilterOutStream的各U类?br /> 2.2.3 用于装以字节ؓ导向的OutputStream
1) DataIOutStreamQ往stream中输出基本类型(int、char{)数据?br /> 2) BufferedOutStreamQ用缓冲区
3) PrintStreamQ生格式化输出
2.2.4 用于装以字Wؓ导向的OutputStream
1) BufferedWriteQ与对应
2) PrintWriteQ与对应
3. RandomAccessFile
1) 可通过RandomAccessFile对象完成Ҏ件的d操作
2) 在生一个对象时Q可指明要打开的文件的性质QrQ只读;wQ只写;rw可读?br /> 3) 可以直接跛_文g中指定的位置
4. I/O应用的一个例?br /> import java.io.*;
public class TestIO{
public static void main(String[] args)
throws IOException{
//1.以行为单位从一个文件读取数?br /> BufferedReader in =
new BufferedReader(
new FileReader("F:\\nepalon\\TestIO.java"));
String s, s2 = new String();
while((s = in.readLine()) != null)
s2 += s + "\n";
in.close();

//1b. 接收键盘的输?br /> BufferedReader stdin =
new BufferedReader(
new InputStreamReader(System.in));
System.out.println("Enter a line:");
System.out.println(stdin.readLine());

//2. 从一个String对象中读取数?br /> StringReader in2 = new StringReader(s2);
int c;
while((c = in2.read()) != -1)
System.out.println((char)c);
in2.close();

//3. 从内存取出格式化输入
try{
DataInputStream in3 =
new DataInputStream(
new ByteArrayInputStream(s2.getBytes()));
while(true)
System.out.println((char)in3.readByte());
}
catch(EOFException e){
System.out.println("End of stream");
}

//4. 输出到文?br /> try{
BufferedReader in4 =
new BufferedReader(
new StringReader(s2));
PrintWriter out1 =
new PrintWriter(
new BufferedWriter(
new FileWriter("F:\\nepalon\\ TestIO.out")));
int lineCount = 1;
while((s = in4.readLine()) != null)
out1.println(lineCount++ + "Q? + s);
out1.close();
in4.close();
}
catch(EOFException ex){
System.out.println("End of stream");
}

//5. 数据的存储和恢复
try{
DataOutputStream out2 =
new DataOutputStream(
new BufferedOutputStream(
new FileOutputStream("F:\\nepalon\\ Data.txt")));
out2.writeDouble(3.1415926);
out2.writeChars("\nThas was pi:writeChars\n");
out2.writeBytes("Thas was pi:writeByte\n");
out2.close();
DataInputStream in5 =
new DataInputStream(
new BufferedInputStream(
new FileInputStream("F:\\nepalon\\ Data.txt")));
BufferedReader in5br =
new BufferedReader(
new InputStreamReader(in5));
System.out.println(in5.readDouble());
System.out.println(in5br.readLine());
System.out.println(in5br.readLine());
}
catch(EOFException e){
System.out.println("End of stream");
}

//6. 通过RandomAccessFile操作文g
RandomAccessFile rf =
new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
for(int i=0; i<10; i++)
rf.writeDouble(i*1.414);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + "Q? + rf.readDouble());
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "rw");
rf.seek(5*8);
rf.writeDouble(47.0001);
rf.close();

rf = new RandomAccessFile("F:\\nepalon\\ rtest.dat", "r");
for(int i=0; i<10; i++)
System.out.println("Value " + i + "Q? + rf.readDouble());
rf.close();
}
}
关于代码的解释(以区为单位)Q?br /> 1ZQ当d文gӞ先把文g内容d~存中,当调用in.readLine()Ӟ再从~存中以字符的方式读取数据(以下U?#8220;~存字节d方式”Q?br /> 1bZQ由于想以缓存字节读取方式从标准IOQ键盘)中读取数据,所以要先把标准IOQSystem.inQ{换成字符导向的streamQ再q行BufferedReader装?br /> 2ZQ要以字W的形式从一个String对象中读取数据,所以要产生一个StringReadercd的stream?br /> 4ZQ对String对象s2d数据Ӟ先把对象中的数据存入~存中,再从~冲中进行读取;对TestIO.out文gq行操作Ӟ先把格式化后的信息输出到~存中,再把~存中的信息输出到文件中?br /> 5ZQ对Data.txt文gq行输出Ӟ是先把基本类型的数据输出屋缓存中Q再把缓存中的数据输出到文g中;Ҏ件进行读取操作时Q先把文件中的数据读取到~存中,再从~存中以基本cd的Ş式进行读取。注意in5.readDouble()q一行。因为写入第一个writeDouble()Q所以ؓ了正显C。也要以基本cd的Ş式进行读取?br /> 6区是通过RandomAccessFilecd文gq行操作?br />
----

重要提示Q?br />
LineNumberInputStreamQStringBufferInputStream已经废除Q大家不要再用!

StringBufferInputStreamQThis class does not properly convert characters into bytesQ?br />
StringBufferInputStreamQDeprecated. This class incorrectly assumes that bytes adequately represent charactersQ?br />

----------------兛_IOQ就是关心你的JAVA前途之路!-----------------------

DataInputStream中已经没有readLine()整个ҎQ?br />
替换为: BufferedReader d=new BufferedReader(new InputStreamReader(in));

--------把字节流转换为字W流接入~存d字符中Q再q行处理Q?br /> q个Ҏ很大的优势!

----------------------
-----------------Why use character streams?------------------
The primary advantage of character streams is that they make it easy to write programs that are not dependent upon a specific character encoding, and are therefore easy to internationalize.
Java stores strings in Unicode, an international standard character encoding that is capable of representing most of the world's written languages. Typical user-readable text files, however, use encodings that are not necessarily related to Unicode, or even to ASCII, and there are many such encodings. Character streams hide the complexity of dealing with these encodings by providing two classes that serve as bridges between byte streams and character streams. The InputStreamReader class implements a character-input stream that reads bytes from a byte-input stream and converts them to characters according to a specified encoding. Similarly, the OutputStreamWriter class implements a character-output stream that converts characters into bytes according a specified encoding and writes them to a byte-output stream.

A second advantage of character streams is that they are potentially much more efficient than byte streams. The implementations of many of Java's original byte streams are oriented around byte-at-a-time read and write operations. The character-stream classes, in contrast, are oriented around buffer-at-a-time read and write operations. This difference, in combination with a more efficient locking scheme, allows the character stream classes to make up for the added overhead of encoding conversion in many cases.

----------标准讑֤System.ind数据------------------
-----------------------------------------------------
d字节QBufferedInputStream
d字符QBufferedReader + InputStreamReader
----------------------------------------------
import java.io.*;

public class systemin
{
public static void main(String args[])
{ try{ //{换!
BufferedReader is=new BufferedReader(new InputStreamReader(System.in))
String inputline=null;
while((inputline=is.readLine())!=null)
System.out.println(inputline);
is.close();
}
catch(IOException e)
{ System,out.println("IOXE: "+e);
}
}
}
--------------------------------------------------------------------------------

-----------------标准输出System.out是一个打印流PrintStream---------------------
import java.io.*;


public class PrintStandardOutput {

public static void main(String[] args) {
String myAnswer = "No, and that's final,";
System.out.println("Hello World of Java");
System.out.println("The answer is " + myAnswer + " at this time.");

PrintWriter pw = new PrintWriter(System.out);
pw.println("The answer is " + myAnswer + " at this time.");


int i = 42;
pw.println(i + '=' + " the answer.");
pw.println("Note: " + i + '=' + " the answer.");
pw.println(i + "=" + " the answer.");
pw.println(i + ('=' + " the answer."));

pw.close();
}
}
-----------------------------------------------------------------------------------
-----------------------要读?输出到—)一个文本文?----------------------------


BufferedReader is=new BufferedReader(new FileReader("xxxx.text"));d
BufferedOutputStream byteout=new BufferedOutputStream(new FileOutputStream("XX.dat"));
// 写出到文本!

-----------------------------------------------

---------------利用 BufferedReader--FileReaderd文本文gQ?----------

---------------在IO中始l要注意是字节流q是字符?---------------------
-----------------------------------------------------------------------
import java.io.*;
import java.awt.*;
import javax.swing.*;
import java.awt.event.*;

class filewindow extends JFrame implements ActionListener
{
JTextArea text;
BufferedReader in;
JButton button;
FileReader file;
filewindow()
{
super("文g字符?);
Container con=getContentPane();
text=new JTextArea(50,50);
text.setBackground(Color.blue);
try{
File f=new File("E:\\a.txt");
file=new FileReader(f);
in=new BufferedReader(file);
/**BufferedReaderQReader in)构造函敎ͼ
*文g自字W读取流FileReader接入BufferedReader
*中Q以便用BufferedReader的对象方法readLine()高效成行dQ?br /> */

}
catch(FileNotFoundException e){}
catch(IOException e){}
button=new JButton("d");
button.addActionListener(this);
con.setLayout(new BorderLayout());
setSize(300,200);
setVisible(true);

con.add(text,"Center");
con.add(button,"South");
addWindowListener(new WindowAdapter()
{public void windowClosing(WindowEvent e)
{setVisible(false);System.exit(0);}});

}
public void actionPerformed(ActionEvent e)
{
String s;
if(e.getSource()==button)
try{
while((s=in.readLine())!=null)
text.append(s+'\n');
//在这里大家还可以用BufferString来暂时保存读取的字符数据Q?br /> }
catch(IOException e1){}
}
//---------main()----------
public static void main(String args[])
{
filewindow win=new filewindow();
win.pack();
}
}


-------------------RandomAccessFile随机d文g---------------
import java.io.*;


public class RandomRead
{
final static String FILENAME="E:\\a.txt";
protected String fileName;
protected RandomAccessFile seeker;

public static void main(String[] argv) throws IOException {
RandomRead r = new RandomRead(FILENAME);

System.out.println("Offset is " + r.readOffset());
System.out.println("Message is \"" + r.readMessage() + "\".");
}

/** Constructor: save filename, construct RandomAccessFile */
public RandomRead(String fname) throws IOException {
fileName = fname;
seeker = new RandomAccessFile(fname, "rw");
}

/** Read the Offset field, defined to be at location 0 in the file. */
public int readOffset() throws IOException {
seeker.seek(0);
seeker.writeChars(FILENAME); // move to very beginning
return seeker.readInt(); // and read the offset
}

/** Read the message at the given offset */
public String readMessage() throws IOException {
seeker.seek(120); // move to where
return seeker.readLine(); // and read the String
}
}

写得很辛?我本来不惛_说什么了,但本着Ҏ术负责的_q是说出?

对于I/O的理解属?U水q?如果java IO有十U的?
错误太多.
对于I/O层次不熟?br /> java IO主要包括
java.io包和java.nio?

java.io主要从四个接口g?
字节:
InputStream/OutputStream,其下为封?qo,特定对象处理的具体实现类.
字符:
Reader/Writer(原文中连Writer接口全都写成Write,以说明Ҏ不了解这了接?如果你经怋用Writer接口怎么会连Writer和Write都分不清,不是一处失?而是全部都是Write)

以上四个接口?底层全部是操作字节的d方式?

java.nio主要以块操作?Buffer)Z,通过可以讑֮的阻塞和非阴塞模?极大地提q了数据输出?br /> 入的性能,而且Channel通过选选择器模式的控制,可以实现在同一输出输入通道上多用户q发q行数据传输?比如一个Socket端口可以同时被无限多(理论上不受限?个客Lq发讉K.是l典的I/O多\复用技?



]]>
[转]Spring2.5的新Ҏ?/title><link>http://www.aygfsteel.com/chenlb/articles/179940.html</link><dc:creator>浪?/dc:creator><author>浪?/author><pubDate>Thu, 14 Feb 2008 07:40:00 GMT</pubDate><guid>http://www.aygfsteel.com/chenlb/articles/179940.html</guid><wfw:comment>http://www.aygfsteel.com/chenlb/comments/179940.html</wfw:comment><comments>http://www.aygfsteel.com/chenlb/articles/179940.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/chenlb/comments/commentRss/179940.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/chenlb/services/trackbacks/179940.html</trackback:ping><description><![CDATA[<br /> <p>从诞生之初,Spring框架坚守它的宗旨:化企业应用开发,同时l复杂问题提供强大的、非侵入性解x案。一q前发布的Spring2.0把q些主题推到了一个新的高度。XML Schema的支持和自定义命名空间的使用大大减少了基于XML的配|。用Java5及更新版本java的开发h员如今可以利用植入了像泛型(genericQ和注解{新语言Ҏ的Spring库。最q,和AspectJ表达式语a的紧密集成,使得以非侵入方式d跨越定义良好的Spring理对象分组的行为成为可能?/p> <p>新发布的Spring2.5l箋坚持了这个发展趋向,特别是ؓ那些使用Java 5或更新版本java的开发h员提供了q一步简化而强大的新特性。这些新Ҏ包括:注解驱动的依赖性注入(annotation-driven dependency injectionQ,使用注解而非XML元数据来自动侦测classpath上的SpringlgQ注解对生命周期Ҏ的支持,一个新的web控制器模型将h映射到加注解的方法上Q在试框架中支持Junit4QSpring XML命名I间的新增内容,{等?/p> <p>本文是探讨这些新Ҏ的3系列文章中的第一。本文将主要x于简化的配置和在Spring应用E序上下文(application contextQ核心新增的Z注解的功能;W二文章将늛web层可用的新特性;最后一文章将着重介l集成和试的新增性能。这一pd的三文章中引用的例子都ZSpring PetClinic应用E序范例。此范例最q被重构以用于展CSpring最新功能,q被包含于Spring 2.5的发布下载包中,可以从Spring Framework <a 文g可以得知关于如何构徏和部|PetClinic应用E序Q掌握本文提到的新技术的最x法也许就是对PetClinic应用E序中所展示的特性进行试验?/p> <h2>Spring支持JSR-250注解</h2> <p>Java EE5中引入了“Javaq_的公共注解(Common Annotations for the Java PlatformQ?#8221;Q而且该公共注解从Java SE 6一开始就被包含其中?2006q?月,BEApȝ宣布了他们在一个名?a >Pitchfork</a>的项目上与Interface21?a >合作</a>Q该目提供了基于Spring的Java EE 5~程模型的实玎ͼ包括支持用于注入QinjectionQ、拦截( interceptionQ和事务处理QtransactionsQ的JSR-250注解和EJB 3注解(JSR-220)??.5版本中,Spring框架?strong>核心QcoreQ?/strong>现在支持以下JSR-250注解Q?/p> <ul> <li>@Resource <li>@PostConstruct <li>@PreDestroy </li> </ul> <p>l合SpringQ这些注解在M开发环境下都可以用——无论是否有应用E序服务器——甚x集成试环境都可以。激z这L支持仅仅是注册一个单独的Spring post-processor的事情:</p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"</font><font color="#3f7f7f">/></font> <br /> </pre> <h3>@Resource注解</h3> <p><strong>@Resource</strong> 注解被用来激zM个命名资源(named resourceQ的依赖注入Q在JavaEE应用E序中,该注解被典型地{换ؓl定于JNDI context中的一个对象?Spring实支持使用<strong>@Resource</strong>通过JNDI lookup来解析对象,默认圎ͼ拥有?strong>@Resource</strong>注解所提供名字相匹配的“bean nameQbean名字Q?#8221;的Spring理对象会被注入?在下面的例子中,Spring会向加了注解的setterҎ传递bean名ؓ“<strong>dataSource</strong>”的Spring理对象的引用?/p> <pre><strong>@Resource(name="dataSource")</strong><br /> <font color="#7f0055"><strong>public void</strong></font> setDataSource(DataSource dataSource) {<br /> <font color="#7f0055"><strong>this</strong></font>.<font color="#0000c0">dataSource</font> = dataSource;<br /> } </pre> <p>直接使用<strong>@Resource</strong>注解一个域QfieldQ同h可能的。通过不暴露setterҎQ代码愈发紧凑ƈ且还提供了域不可修改的额外益处。正如下面将要证明的Q?strong>@Resource</strong>注解甚至不需要一个显式的字符串|在没有提供Q何值的情况下,域名被当作默认倹{?/p> <pre>@Resource<br /> <font color="#7f0055"><strong>private</strong></font> DataSource dataSource; <font color="#3f7f5f">// inject the bean named 'dataSource'</font> </pre> <p>该方式被应用到setterҎ的时候,默认名是从相应的属性衍生出来,换句话说Q命名ؓ<strong>'setDataSource'</strong>的方法被用来处理名ؓ<strong>'dataSource'</strong>的属性?/p> <pre><font color="#7f0055"><strong>private</strong></font> DataSource <font color="#0000c0">dataSource</font>;<br /> @Resource<br /> <font color="#7f0055"><strong>public void</strong></font> setDataSource(DataSource dataSource) {<br /> <font color="#7f0055"><strong>this</strong></font>.<font color="#0000c0">dataSource</font> = dataSource;<br /> } </pre> <p>?strong>@Resource</strong>没有昑ּ提供名字的时候,如果Ҏ默认名字找不到对应的Spring理对象Q注入机制会回滚至类型匹配(type-matchQ。如果刚好只有一个Spring理对象W合该依赖的cdQ那么它会被注入。通过讄<strong>CommonAnnotationBeanPostProcessor</strong> ?strong>‘fallbackToDefaultTypeMatch’</strong>属性ؓ“false”Q默认值是“true”Q可以禁用这一Ҏ?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><property</font> <font color="#7f007f">name</font>=<font color="#2a00ff">"fallbackToDefaultTypeMatch"</font> <font color="#7f007f">value</font>=<font color="#2a00ff">"false"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></bean></font> </pre> <p>正如上文所提到的,在解析标?strong>@Resource</strong>注解的依赖时QSpring支持JNDI-lookup。如若要强制Ҏ有?strong>@Resource</strong>注解的依赖进行JNDI lookupQ那也只要将<strong>CommonAnnotationBeanPostProcessor</strong>?strong>'alwaysUseJndiLookup'</strong> 标识讄为true可以了Q默认值是falseQ?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.context.annotation.CommonAnnotationBeanPostProcessor"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><property</font> <font color="#7f007f">name</font>=<font color="#2a00ff">"alwaysUseJndiLookup"</font> <font color="#7f007f">value</font>=<font color="#2a00ff">"true"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></bean></font></pre> <p>另一个选择是,ȀzL定ؓ‘resource-ref-mappings’的依据全局JNDI名的查找Q在<strong>@Resource</strong>注解内提?#8216;<strong>mappedName’</strong>属性。即使目标对象实际上是一个JNDI资源Q仍然推荐引入一个Spring理对象Q这样可以提供一个间接层q且因此降低耦合E度。自Spring2.0开始添加命名空间以来,定义一个委托Spring处理JNDI lookup的bean也变得愈发简l:</p> <pre><font color="#3f7f7f"><jee:jndi-lookup</font> <font color="#7f007f">id</font>=<font color="#2a00ff">"dataSource"</font> <font color="#7f007f">jndi-name</font>=<font color="#2a00ff">"java:comp/env/jdbc/petclinic"</font><font color="#3f7f7f">/></font> <br /> </pre> <p>q个Ҏ的优点在于间接层带来了巨大的部vҎ。比如说Q一个单独的pȝ试环境应该不再需要JNDI注册。在q种情况下,在系l测试配|中可以提供如下的bean定义Q?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">id</font>=<font color="#2a00ff">"dataSource"</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.jdbc.datasource.DriverManagerDataSource"</font><br /> <font color="#7f007f">p:driverClassName</font>=<font color="#2a00ff">"${jdbc.driverClassName}"</font><br /> <font color="#7f007f">p:url</font>=<font color="#2a00ff">"${jdbc.url}"</font><br /> <font color="#7f007f">p:username</font>=<font color="#2a00ff">"${jdbc.username}"</font><br /> <font color="#7f007f">p:password</font>=<font color="#2a00ff">"${jdbc.password}"</font><font color="#3f7f7f">/></font> </pre> <p>Z提一下,上面的例子中Q实际的JDBCq接属性从一个属性文Ӟproperties fileQ解析而来Q在q个属性文仉Q关键字与提供的${占位W}互相对应Q这需要注册一个名?strong>PropertyPlaceholderConfigurer</strong>?strong>BeanFactoryPostProcessor</strong>实现来完成。这是具体化那些属性(通常是针对特定环境的属性)常用的技术,q些属性可能比其他配置修改得更为频J?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><property</font> <font color="#7f007f">name</font>=<font color="#2a00ff">"location"</font> <font color="#7f007f">value</font>=<font color="#2a00ff">"classpath:jdbc.properties"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></bean></font> </pre> <p>Srping2.5中新加入?#8216;context’命名I间Q这个命名空间让我们能够得到更ؓz的方式来实现属性占位符Qproperty placeholderQ的配置Q?/p> <pre><font color="#3f7f7f"><context:property-placeholder</font> <font color="#7f007f">location</font>=<font color="#2a00ff">"classpath:jdbc.properties"</font><font color="#3f7f7f">/></font><br /> </pre> <h3>生命周期注解Q@PostConstruct和@PreDestroy</h3> <p><strong>@PostConstruct</strong> ?strong>@PreDestroy</strong>注解分别用来触发Spring的初始化和销毁回调。这个特性在原有基础上得C扩展Q但q没有替代在Spring2.5之前版本中提供的同样的回调的另两个选项。第一个选项是实现Spring?strong>InitializingBean</strong> ?strong>DisposableBean</strong> 接口中的一个或两个。这两个接口都需要一个回调方法的实现(分别?strong>afterPropertiesSet()</strong>?strong>destroy()</strong> )。这U基于接口的Ҏ利用了Spring自动识别M实现q些接口的Spring理对象的能力,因而不再需要另外的配置。另一斚wQSpring的一个关键目标是可能的非R入。因此,许多Spring用户q不采用实现q些Spring特定接口的方法,而利用第二个选项Q那是提供他们自己的初始化和销毁方法。尽入侉|小Q但~点在于使用q个方式的话必L式声?strong>bean</strong>元素?strong>init-method</strong>?strong>destroy-method</strong>属性。显式配|有时候是必须的,例如当回调需要在开发h员控制能力之外的代码上被调用的时候。PetClinic应用E序很好地说明了q个场景。当它和JDBC配置一赯行的时候,会用C个第三方<strong>DataSource</strong>Qƈ且它昑ּ声明了一?strong>destroy-method</strong>。另外要注意到的是,单独的连接池数据源是<strong>dataSource</strong>的另一个部|选项Qƈ且不需要修改Q何代码?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">id</font>=<font color="#2a00ff">"dataSource"</font><br /> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.apache.commons.dbcp.BasicDataSource"</font><br /> <strong>destroy-method="close"</strong><br /> <font color="#7f007f">p:driverClassName</font>=<font color="#2a00ff">"${jdbc.driverClassName}"</font><br /> <font color="#7f007f">p:url</font>=<font color="#2a00ff">"${jdbc.url}"</font><br /> <font color="#7f007f">p:username</font>=<font color="#2a00ff">"${jdbc.username}"</font><br /> <font color="#7f007f">p:password</font>=<font color="#2a00ff">"${jdbc.password}"</font><font color="#3f7f7f">/></font> </pre> <p>在用Spring2.5的过E中Q如果一个对象需要调用一个初始化的回调方法的话,q个回调Ҏ可以采用<strong>@PostConstruct</strong>来注解。例如一个假想的例子Q一个后CQ务需要在启动的时候就开始对一个文件目录进行轮询:</p> <pre><font color="#7f0055"><strong>public class</strong></font> FilePoller {<br /> <br /> <strong>@PostConstruct</strong><br /> <font color="#7f0055"><strong>public void</strong></font> startPolling() {<br /> ...<br /> }<br /> ...<br /> } </pre> <p>cM圎ͼ一个在Spring理对象上用<strong>@PreDestroy</strong>注解的方法会在这个对象寄宿的应用E序上下文(application contextQ关闭的时候被调用?/p> <pre><font color="#7f0055"><strong>public class</strong></font> FilePoller {<br /> <br /> <strong>@PreDestroy</strong><br /> <font color="#7f0055"><strong>public void</strong></font> stopPolling() {<br /> ...<br /> }<br /> ...<br /> } </pre> <p>在添加了对JSR-250注解的支持以后,现在的Spring2.5l合前面提到的两U生命周期方法的长处。将<strong>@PostConstruct</strong>?strong>@PreDestroy</strong>作ؓҎ层注解加入,_以实现在受Spring理的上下文QcontextQ中触发回调。换句话_不需要另外基于XML的配|。同Ӟq两个注解是Java语言本n的一部分Q甚臌包括在Java SE 版本6中)Q所以无需引入特定Spring包。这两个注解拥有在其他环境中也能理解的标识语义的优点Q随着旉的推U,Java开发h员可能会发现q些注解在第三方开发库中被来多的运用到。最后,Z注解生命周期回调的其中一个有的l果是,不止一个方法可以带有这两个注解中的M一个,q且所有注解了的方法会被调用?/p> <p>Ȁzd刚描q的关于<strong>@Resource</strong> ?strong>@PostConstruct</strong>?strong>@PreDestroy</strong>注解的所有行为,正如上文提到的,需要ؓSpring?strong>CommonAnnotationBeanPostProcessor</strong>提供一个bean定义。但另一个更l的Ҏ则可能是使用2.5中的新的context命名I间Q?/p> <pre><font color="#3f7f7f"><strong><context:annotation-config/></strong></font><br /> </pre> <p>引入q个单个元素不单单注册一?strong>CommonAnnotationBeanPostProcessor</strong>Q也会像下文叙q的那样Ȁz自动装配(autowireQ行为?strong>CommonAnnotationBeanPostProcessor</strong>也ؓ<strong>@WebServiceRef</strong> ?strong>@EJB</strong>注解提供支持。这些将在本文系列的W三中和Spring2.5Z业集成提供的其他新特性一赯论?/p> <h2>利用注解来优化细_度自动装配</h2> <p>늛Spring对自动装配支持的文档中常怼提到׃自动装配机制的粗_度而伴随有很多限制性。Spring2.5之前Q自动装配可以通过很多不同的方式来配置Q构造器Q类型setterQ名字setterQ或者自动侦(在该方式中Spring选择自动装配一个构造器或者类型setterQ。这些不同的选择实提供了很大程度的灉|性,但它们中没有一个方法能够提供细_度控制。换句话_Spring2.5之前q不可能自动装配某个对象setterҎ的特定子集,或者通过cd或名字来自动装配它的一些属性。结果,许多Spring用户意识到将自动装配应用到构建原型和试中的好处Q但当提到在产品中维护和支持pȝӞ大部分h认ؓQ加入冗长的昑ּ配置对于澄清它所担负的职责是非常值得的?/p> <p>然而,Spring2.5大幅度地改变了布局。如上文所qͼ自动配置选项现在已经被扩展,支持JSR-250<strong> @Resource</strong>注解来激zd每个Ҏ或域基础上被命名资源的自动装配。然而,<strong>@Resource</strong>注解若单独用的话有很多限制。因此,Sring2.5引进了一个名?strong>@Autowired</strong>的注解进一步提高控制别。ؓȀz这里所讲的行ؓ需要注册一个单独的bean定义Q?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"</font><font color="#3f7f7f">/></font><br /> </pre> <p>另外如上文提到的Qcontext命名I间提供了一个更明的Ҏ。它激zL文所讨论的两个post-processorQ?strong>AutowiredAnnotationBeanPostProcessor</strong>?strong>CommonAnnotationBeanPostProcessor</strong>Q和我们在Spring2.0中引入的Z注解的post-processorQ?strong>RequiredAnnotationBeanPostProcessor</strong>?strong>PersistenceAnnotationBeanPostProcessor</strong>?/p> <pre><font color="#3f7f7f"><context:annotation-config/></font><br /> </pre> <p>利用<strong>@Autowired</strong> 注解可以对相应类型注入依赖。域、构造器和方法都可以ȀzL行ؓ。实际上QaotowiredҎq不一定要是setterҎQ且可以接受多个参数。下面这个例子是完整的可接受的用法:</p> <pre><strong>@Autowired</strong><br /> <font color="#7f0055"><strong>public void</strong></font> setup(DataSource dataSource, AnotherObject o) { ... } </pre> <p>默认圎ͼ标有<strong>@Autowired</strong>注解的依赖被认ؓ是必ȝ。然而,也可以将<strong>required</strong>属性D|ؓ<strong>false</strong>来声明它们中的Q何一个。在下面q个例子中,<strong>DefaultStrategy</strong>只有在context命名I间中没?strong>SomeStrategy</strong>cd的Spring理对象时才能被使用?/p> <pre><strong>@Autowired(required=false)</strong><br /> <font color="#7f0055"><strong>private</strong></font> SomeStrategy <font color="#2a00c0">strategy</font> = <font color="#7f0055">new</font> DefaultStrategy(); </pre> <p>通过cdq行的自动装配明昑֜在Spring context包含多于一个期望类型的对象的时候造成歧义。默认地Q如果一个必ȝ依赖没不是恰好一个bean与之对应的话Q自动装配机制就会失败。同LQ对于Q何一个可选属性,如果它拥有一个以上的候选,也都会失败(如果属性可选且没有M候选可用的话,该属性则会被单地跌Q。有很多不同的配|选项可以避免q些冲突?/p> <p>若Context中拥有一个指定类型的一?strong>d?/strong>实例Q对q个cd定义的bean定义应该包含‘primary’属性。当Context中含有其他可用实例的时候这个方法就很适用Q但那些非主关键实例L昑ּ配置的?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">id</font>=<font color="#2a00ff">"dataSource"</font> <strong>primary="true"</strong> ... <font color="#3f7f7f">/></font> <br /> </pre> <p>在需要更多控制的时候,Mautowired的域、构造参数、或者方法参数可以进一步加?strong>@Qualifier</strong>注解。qualifier可以包含一?strong>字符?/strong>|在这U情况下QSpring会试N过名字来找到对应的对象?/p> <pre>@Autowired<br /> <strong>@Qualifier("primaryDataSource")</strong><br /> <font color="#7f0055"><strong>private</strong></font> DataSource dataSource; </pre> <p><strong>@Qualifier</strong>作ؓ一个独立注解存在的主要原因是它可以被应用在构造器参数或方法参CQ但上文提到?strong>@Autowired</strong>注解只能q用在构造器或方法本w?/p> <pre>@Autowired<br /> <font color="#7f0055"><strong>public void</strong></font> setup(<strong>@Qualifier("primaryDataSource")</strong> DataSource dataSource, AnotherObject o) { ... } </pre> <p>事实上,<strong>@Qualifier</strong>作ؓ一个单独的注解在定制化斚w提供了更多的好处。用戯定义的注解在自动装配q程中也可以起到qualifier的作用,最单的实现方式是在q用自定义注解的同时?strong>@Qualifier</strong>作ؓ它的元注解?/p> <pre>@Target({ElementType.<em>FIELD</em>, ElementType.<em>PARAMETER</em>, ElementType.<em>TYPE</em>, ElementType.<em>ANNOTATION_TYPE</em>})<br /> @Retention(RetentionPolicy.<em>RUNTIME</em>)<br /> <strong>@Qualifier</strong><br /> <font color="#7f0055"><strong>public @interface</strong></font> VetSpecialty { ... } </pre> <p>自定义注解可以选择包含一个值来提供通过名字匚w的功能,但更普遍的用法是它作ؓ“标记”注解或定义一个对qualifierq程提供一些更多含义的倹{例如,下面q个摘录则描l了一个域Q它应该和通过名字匚w得到的结果中合格的对象进行自动装配?/p> <pre>@Autowired<br /> <strong>@VetSpecialty("dentistry")</strong><br /> <font color="#7f0055"><strong>private</strong></font> Clinic dentistryClinic; </pre> <p>在用XML配置来达C赖解析的目标Ӟ<strong>'qualifier'</strong> 子元素可以被加注到bean定义中。在下文的组件扫描部分,我们呈C个可供选择的非XMLҎ?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">id</font>=<font color="#2a00ff">"dentistryClinic"</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"samples.DentistryClinic"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><qualifier</font> <font color="#7f007f">type</font>=<font color="#2a00ff">"example.VetSpecialty"</font> <font color="#7f007f">value</font>=<font color="#2a00ff">"dentistry"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></bean></font> </pre> <p>Z避免?strong>@Qualifier</strong>注解的Q何依赖性,可以在Spring context中提供一?strong>CustomAutowireConfigurer</strong>的bean定义q直接注册所有自定义注解cdQ?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.beans.factory.annotation.CustomAutowireConfigurer"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><property</font> <font color="#7f007f">name</font>=<font color="#2a00ff">"customQualifierTypes"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><set></font><br /> <font color="#3f7f7f"><value></font>example.VetSpecialty<font color="#3f7f7f"></value></font><br /> <font color="#3f7f7f"></set></font><br /> <font color="#3f7f7f"></property></font><br /> <font color="#3f7f7f"></bean></font> </pre> <p>现在Q自定义修饰W被昑ּ声明了,׃再需?strong>@Qualifier</strong>q个元注解符了?/p> <pre>@Target({ElementType.<em>FIELD</em>, ElementType.<em>PARAMETER</em>, ElementType.<em>TYPE</em>, ElementType.<em>ANNOTATION_TYPE</em>})<br /> @Retention(RetentionPolicy.<em>RUNTIME</em>)<br /> <font color="#7f0055"><strong>public @interface</strong></font> VetSpecialty { ... } </pre> <p>其实Q在配置<strong>AutowiredAnnotationBeanPostProcessor</strong>的时候,取代<strong>@Autowired</strong>注解都是有可能的?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><property</font> <font color="#7f007f">name</font>=<font color="#2a00ff">"autowiredAnnotationType"</font> <font color="#7f007f">value</font>=<font color="#2a00ff">"example.Injected"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></bean></font> </pre> <p>大部分情况下Q定义自定义‘标记’注解的能力结合通过名字或其他文法D行匹配选项Q以完成自动装配过E的l粒度控制。但Springq支持在qualifier注解上Q意数目的L属性。比如,下面是一个极为细_度修饰的例子?/p> <pre><strong>@SpecializedClinic(species="dog", breed="poodle")</strong><br /> <font color="#7f0055"><strong>private</strong></font> Clinic poodleClinic; </pre> <p>自定义修饰符的实现应该定义这些属性:</p> <pre>@Target({ElementType.<em>FIELD</em>, ElementType.<em>PARAMETER</em>, ElementType.<em>TYPE</em>, ElementType.<em>ANNOTATION_TYPE</em>})<br /> @Retention(RetentionPolicy.<em>RUNTIME</em>)<br /> @Qualifier<br /> <font color="#7f0055"><strong>public @interface</strong></font> SpecializedClinic {<br /> <br /> <strong>String species();</strong><br /> <br /> <strong>String breed();</strong><br /> <br /> } </pre> <p>自定义修饰符<strong>属?/strong>可以匚w那些XML中bean定义?strong>qualifier</strong>注解的属性子元素。这些元素通常以键Q值对方式提供?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">id</font>=<font color="#2a00ff">"poodleClinic"</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"example.PoodleClinic"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><qualifier</font> <font color="#7f007f">type</font>=<font color="#2a00ff">"example.SpecializedClinic"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><attribute</font> <font color="#7f007f">key</font>=<font color="#2a00ff">"species"</font> <font color="#7f007f">value</font>=<font color="#2a00ff">"dog"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"><attribute</font> <font color="#7f007f">key</font>=<font color="#2a00ff">"breed"</font> <font color="#7f007f">value</font>=<font color="#2a00ff">"poodle"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></qualifier></font><br /> <font color="#3f7f7f"></bean></font> </pre> <p>目前为止Q关于autowire的描q都只是针对单独的实例,其实也支持集合。在M需要得到所有context中某U特定类型的Spring理对象的时候,只需要简单地在一个强cdQstrongly-typedQ集合上加注<strong>@Autowired</strong> 注解?/p> <pre>@Autowired<br /> <font color="#7f0055"><strong>private</strong></font> List<Clinic> <font color="#2a00c0">allClinics</font>; </pre> <p>本章节最后一个值得指出的特性是自动装配的用替代了Spring的Aware接口。在Spring2.5之前Q如果某个对象需要一个Spring context?strong>ResourceLoader</strong>的引用,它可以通过实现<strong>ResourceLoaderAware</strong>的方式得Spring通过<strong>setResourceLoader</strong>(<strong>ResourceLoader resourceLoader</strong>)Ҏ来提供该依赖。借助同样的方法可以得到Spring理?strong>MessageSource</strong>的引用,甚至可以得到<strong>ApplicationContext</strong>本n。对于Spring2.5用户而言Q这个行为现在通过autowiring得到全面支持Q需要指出的是包含这些Spring特定依赖的时候应该考虑周到Q特别是它们只能用于从业务逻辑清楚地分割出来的基础构架代码中)?/p> <pre>@Autowired<br /> <font color="#7f0055"><strong>private</strong></font> MessageSource messageSource;<br /> <br /> @Autowired<br /> <font color="#7f0055"><strong>private</strong></font> ResourceLoader resourceLoader;<br /> <br /> @Autowired<br /> <font color="#7f0055"><strong>private</strong></font> ApplicationContext applicationContext;<br /> </pre> <h2>自动侦测Springlg</h2> <p>?.0版本开始,Spring引入了构造型QstereotypeQ注解的概念以及?strong>@Repository</strong>注解作ؓ数据讉K代码的标记的Ҏ。在此基上,Spring2.5又加入了两个新的注解 —?<strong>@Service</strong>?strong>@Controller</strong> 来完成ؓ通常的三层架构(数据讉K对象、服务、web控制器)角色委Q。Spring2.5也引入了泛型<strong>@Component</strong>注解Q其他构造型可从逻辑上对其进行扩展。通过清晰地指明应用程序的角色Q这些构造型方便了Spring AOP和post-processor的用,q些post-processorl基于这些角色的加了注解的对象提供了附加行ؓ。比如,Spring2.0引入?strong>PersistenceExceptionTranslationPostProcessor</strong>对Q何带?strong>@Repository</strong> 注解的对象自动激zd数据讉K异常转换?/p> <p>q些注解同样可以l合Spring2.5其他一些新性能来用:自动侦测classpath上的lg。尽XML已经成ؓ最常见的Spring元数据的格式Q但它决不是唯一选择。实际上QSpring容器内的元数据是qJava来表C的Q当XML被用来定义Spring理对象Ӟ在实例化q程之前Q那些定义会被解析ƈ转化成Java对象。Spring2.5的一个巨大的新功能是支持从源码层注解d元数据。因而,上文描述的自动装配机制用注解的元数据来注入依赖Q但它仍焉要注册至一个bean定义以便提供每个Spring理对象的实现类。组件扫描功能则使得q个XML中最L的bean定义都不再存在需求性?/p> <p>正如上面所C,Spring注解驱动的自动装配可以在不牺牲细_度控制的前提下极大E度地减XML的用。组件侦机制将q个优点更发扬光大。全面替代XML中的配置不再必要Q组件扫描反而可以处理XML元数据来化整体配|。结合XML和注解驱动技术可以得C个^衡优化的ҎQ这?.5版本的PetClinic范例中有详细阐述。在该范例中Q基构架lgQ数据源、事务管理等Q结合上文提到的外化属性在XML中定义。数据访问层对象也有部分在XML中定义,它们的配|也都利用了<strong>@Autowired</strong>注解来简化依赖注入。最后,web层控制器完全不在XML中显式定义,相反Q下面提供的q段配置被用来触发所有web控制器的自动侦测Q?/p> <pre><strong><font color="#3f7f7f"><context:component-scan</font> <font color="#7f007f">base-package</font>=<font color="#2a00ff">"org.springframework.samples.petclinic.web"</font><font color="#3f7f7f">/></font></strong><br /> </pre> <p>需要注意到的是q段CZ中用到了base-package属性。组件扫描的默认匚w规则会递归侦测该包Q多个包可以以逗号分隔的list方式提供Q内的所有类的所有Spring构造型注解。正因ؓ如此QPetClinic应用E序范例中的各类控制器的实现都采用了<strong>@Controller</strong>注解QSpring?strong>内置</strong>构造型之一Q。请看下面这个例子:</p> <pre><strong>@Controller</strong><br /> <font color="#7f0055"><strong>public class</strong></font> ClinicController {<br /> <br /> <font color="#7f0055"><strong>private final</strong></font> Clinic <font color="#2a00c0">clinic</font>;<br /> <br /> @Autowired<br /> <font color="#7f0055"><strong>public</strong></font> ClinicController(Clinic clinic) {<br /> <font color="#7f0055"><strong>this</strong></font>.<font color="#2a00c0">clinic</font> = clinic;<br /> }<br /> ... </pre> <p>自动侦测lg在Spring容器中注册,像它们在XML中被定义一栗如上所C,那些对象可以轮流利用注解驱动的自动装配?/p> <p>lg扫描的匹配规则可以通过qo器(filterQ来自定义,以根据类型、AspectJ表达式、或针对命名模式的正则表辑ּ来决定包含或不包含哪些组件。默认的构造型也可以被用。比如这里有一个配|的例子Q这个配|会忽略默认的构造型Q但会自动侦名字以Stub打头或者包?strong>@Mock</strong>注解的所有类Q?/p> <pre><font color="#3f7f7f"><context:component-scan</font> <font color="#7f007f">base-package</font>=<font color="#2a00ff">"example"</font> <font color="#7f007f">use-default-filters</font>=<font color="#2a00ff">"false"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><context:include-filter</font> <font color="#7f007f">type</font>=<font color="#2a00ff">"aspectj"</font> <font color="#7f007f">expression</font>=<font color="#2a00ff">"example..Stub*"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"><context:include-filter</font> <font color="#7f007f">type</font>=<font color="#2a00ff">"annotation"</font> <font color="#7f007f">expression</font>=<font color="#2a00ff">"example.Mock"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></context:component-scan></font> </pre> <p>cd匚w的限制性也可以用排他的qo器控制。例如,<strong>除了@Repository</strong>注解外其他都依赖于默认过滤器Q那么就需要加入一?strong>排他qo?/strong>(<strong>exclude-filter</strong>)?/p> <pre><font color="#3f7f7f"><context:component-scan</font> <font color="#7f007f">base-package</font>=<font color="#2a00ff">"example"</font><font color="#3f7f7f">></font><br /> <font color="#3f7f7f"><context:exclude-filter</font> <font color="#7f007f">type</font>=<font color="#2a00ff">"annotation"</font> <font color="#7f007f">expression</font>=<font color="#2a00ff">"org.springframework.stereotype.Repository"</font><font color="#3f7f7f">/></font><br /> <font color="#3f7f7f"></context:component-scan></font> </pre> <p>很明显,有很多方法可以扩展组件扫描来注册自定义的cd。构造型注解是最单的选择Q所以构造型概念本n也是可扩展的。像先前提到的,<strong>@Component</strong>?strong>泛型</strong>模型Q?strong>@Repository</strong>?strong>@Service</strong>,?strong>@Controller</strong>注解都从该构造型逻辑扩展而得。正因ؓ如此Q?strong>@Component</strong>可被用来作ؓ元注解(也就是说Q在另外的注解上声明的注解)Q所有具?strong>@Component</strong>元注解的自定义注解都会被默认扫描匚w规则自动侦测到。一个例子就有希望让你领会到其实它根本没有听h那么难?/p> <p>让我们回想一下在?strong>@PostConstruct</strong>?strong>@PreDestroy</strong>生命周期注解的时候的假想的后CQ务。也怸个应用程序有很多很多q样的后CQ务,q些d实例需要XML bean定义以便在Spring context里注册ƈ使它们自q生命周期Ҏ在正时候被调用。利用组件扫描就不再需要这些显式的XML bean定义。如果这些后CQ务都实现一个相同的接口或者都沿用同样的命名惯例,那么可以?strong>include-filters</strong>。然而,更简单的Ҏ是ؓq些d对象创徏一个注解ƈ提供<strong>@Component</strong>元注解?/p> <pre>@Target({ElementType.<em>TYPE</em>})<br /> @Retention(RetentionPolicy.<em>RUNTIME</em>)<br /> @Documented<br /> <strong>@Component</strong><br /> <font color="#7f0055"><strong>public @interface</strong></font> BackgroundTask {<br /> String value() <font color="#7f0055"><strong>default</strong></font> <font color="#0000c0">""</font>;<br /> } </pre> <p>然后在所有后CQ务的cd义中提供自定义构造型注解?/p> <pre><strong>@BackgroundTask</strong><br /> <font color="#7f0055"><strong>public class</strong></font> FilePoller {<br /> <br /> @PostConstruct<br /> <font color="#7f0055"><strong>public void</strong></font> startPolling() {<br /> ...<br /> }<br /> <br /> @PreDestroy<br /> <font color="#7f0055"><strong>public void</strong></font> stopPolling() {<br /> ...<br /> }<br /> ...<br /> } </pre> <p>泛型<strong>@Component</strong>注解可以像例子中提供的那L单用,自定义注解技术则提供了一个用更h义的、领域特定的名字的机会。这些领域特定注解提供更深入的机会,比如使用AspectJ切点表达式来识别所有后CQ务,以便增加advice来监控这些Q务的zd性?/p> <p>默认的,lg被侦到的时候,Spring会自动生成一个没有修饰符的类名作为bean名字。上一个例子中Q生成的bean名字会是filePoller。但是,M加注了Spring构造型注解Q?strong>@Component</strong>?strong>@Repository</strong>?strong>@Service</strong>?<strong>@Controller</strong>Q或是加注了其他的以@Component作ؓ元注解的注解Q比如上面例子中?strong>@BackgroundTask</strong> Q的c,构造型注解?strong>value</strong>属性可以被昑ּ指定Q实例将该g为它的bean名字注册到context中。接下来的例子里Q实例名应该是petClinic而不是默认生成的名字simpleJdbcClinic?/p> <pre><strong>@Service("petClinic")</strong><br /> <font color="#7f0055"><strong>public class</strong></font> SimpleJdbcClinic {<br /> ...<br /> } </pre> <p>同样的,在下面修正版的FilePoller例子里,生成的bean名字应该是poller而不是filePoller?/p> <pre><strong>@BackgroundTask("poller")</strong><br /> <font color="#7f0055"><strong>public class</strong></font> FilePoller {<br /> ...<br /> } </pre> <p>虽然所有Spring理对象都被默认地当?strong>单例</strong>实例来处理,但有些时候还是有必要为某个对象指明一个备用的范围QscopeQ。D个例子来_在web层,一个Spring理对象可能捆绑到request或session的范围。对?.0版本QSpring的scope机制更具延展性,q样一来,自定义scope可以被注册到应用E序上下文(application contextQ。在XML配置中,仅仅是简单地包含q?strong>scope</strong>属性及该scope的名字就可以了?/p> <pre><font color="#3f7f7f"><bean</font> <font color="#7f007f">id</font>=<font color="#2a00ff">"shoppingCart"</font> <font color="#7f007f">class</font>=<font color="#2a00ff">"example.ShoppingCart"</font> <strong>scope=<font color="#2a00ff">"session"</font></strong><font color="#3f7f7f">></font><br /> ...<br /> <font color="#3f7f7f"></bean></font> </pre> <p>Spring2.5中,扫描的组件提?strong>@Scope</strong>注解可以起到同样的作用?/p> <pre>@Component<br /> <strong>@Scope("session")</strong><br /> <font color="#7f0055"><strong>public class</strong></font> ShoppingCart {<br /> ...<br /> } </pre> <p>q里要指出的最后一Ҏ使用lg扫描时qualifier注解应用是多么的单。在上一节,下面q个对象曾被作ؓ使用自定义qualifier注解q行自动装配的例子:</p> <pre><strong>@VetSpecialty("dentistry")</strong><br /> <font color="#7f0055"><strong>private</strong></font> Clinic <font color="#2a00c0">dentistryClinic</font>; </pre> <p>同样的例子接着展现了在XML内?#8216;qualifier’元素Z赖提供指定目标bean定义。在使用lg扫描ӞXML元数据不是必ȝ。但自定义修饰符也许在目标类定义中被作ؓcd层注解而引入。另一个将被扫描的<strong>@Repository</strong>实例作ؓ依赖的例子如下:</p> <pre>@Repository<br /> <strong>@VetSpecialty("dentistry")</strong><br /> <font color="#7f0055"><strong>public class</strong></font> DentistryClinic <font color="#7f0055"><strong>implements</strong></font> Clinic {<br /> ...<br /> } </pre> <p>最l,因ؓ前面的例子展C自定义注解及?strong>属?/strong>的例子,相等同的非XML表示依赖目标的方法如下:</p> <pre>@Repository<br /> <strong>@SpecializedClinic(species="dog", breed="poodle")</strong><br /> <font color="#7f0055"><strong>public class</strong></font> PoodleClinic <font color="#7f0055"><strong>implements</strong></font> Clinic {<br /> ...<br /> } </pre> <h2>结</h2> <p>Spring2.5在很多方面都提供了很有意义的新功能。本文主要关注于怎样通过掌控Java注解的力量将配置化。就如在JSR-250中定义的那样QSpring支持公共注解QCommon AnnotationsQ,同时动装配过E的更细_度的控制提供了额外注解。Spring2.5也扩展了从Spring2.0?strong>@Repository</strong>开始的构造型QstereotypeQ注解,q且所有这些构造型注解都可以和新的lg扫描功能l合使用。Spring2.5仍然全面支持ZXML的配|,同时它又引进了一个新的context命名I间对常见配|场景提供更_要的文法。实际上Q支持XML和基于注解配|的无缝l合最l生一个更为^衡的全面的方法。基本构架的复杂配置可以在模块XML文g中定义,而应用程序栈日益增多地更高层配置可以更多的从Z注解的技术中L——前提是都在同一个Spring2.5应用E序context内?/p> <p>在接下来的文章中Q我们将讨论到在Spring web层强大的Z注解的新功能V敬请关注该pd的下一文章?</p> <strong>查看英文原文Q?/strong><a s New in Spring 2.5: Part 1</a>  <br /> <br /> <p id="TBPingURL">Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=2054220<br /> <br /> 转:<a >http://blog.csdn.net/andilyliao/archive/2008/01/20/2054220.aspx</a></p> <img src ="http://www.aygfsteel.com/chenlb/aggbug/179940.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/chenlb/" target="_blank">浪?/a> 2008-02-14 15:40 <a href="http://www.aygfsteel.com/chenlb/articles/179940.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转蝲]Java开发技术十q的回顾与展?/title><link>http://www.aygfsteel.com/chenlb/articles/89974.html</link><dc:creator>浪?/dc:creator><author>浪?/author><pubDate>Mon, 25 Dec 2006 12:30:00 GMT</pubDate><guid>http://www.aygfsteel.com/chenlb/articles/89974.html</guid><wfw:comment>http://www.aygfsteel.com/chenlb/comments/89974.html</wfw:comment><comments>http://www.aygfsteel.com/chenlb/articles/89974.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.aygfsteel.com/chenlb/comments/commentRss/89974.html</wfw:commentRss><trackback:ping>http://www.aygfsteel.com/chenlb/services/trackbacks/89974.html</trackback:ping><description><![CDATA[[转蝲] <a >http://news.csdn.net/n/20061219/99619.html</a><br /><br /><br />    从JDK诞生到现在已l有11q的旉了。hC瞬间。{?1q过MQJDK已经发布?个版本。在q?1q里诞生了无数和Java相关的技术和标准。现在让我们q入旉隧道Q重新回?995q_再来回顾一下Java的发展轨q和历史变迁?<br /><br />  <strong>一?JDK前传</strong><br /><br />  在这个世界上Q熟悉Java历史的h非常多,如果要问一个hJava是从哪年诞生的,也许大多Ch都会回答?995q_q个非常好记Q因为微软的Windows95也是在这一q发布的Q。但事实上Java早在上个世纪90q代初就开始酝酿了?<br /><br />  1991q?月,Sun公司的James Gosling领导的绿色计?Green Project)开始着力发展一U分布式pȝl构Q其能够在各种消费性电子品上q行。而Green目l的成员一开始用C++语言来完成这个项目,׃Green目l的成员都具有C++背景Q所以他们首先把目光锁定了C++~译器,Gosling首先改写了C++~译器,但很快他感到C++的很多不I需要研发一U新的语aJava来替代它Q一杯飘香的咖啡成ؓ了它的标志?<br /><br />  ?7 个月后,整个pȝ完成了,q个pȝ是更注重机顶盒式的操作系l,不过在当时市Z成熟的情况下Q他们的目没有获得成功Q但Java语言却得CSun总裁McNealy的赏识?<br /> <br />  直至 1994q下半年Q由于Internet的迅猛发展和环球信息|?WWW的快速增长,W一个全球信息网l浏览器Mosaic诞生了;此时Q工业界寚w合在网l异构环境下使用的语a有一U非常急迫的需求;Games Gosling军_改变l色计划的发展方向,他们对Oakq行了小规模的改造,pPJava?995q的3?3日诞生了QJava的诞生标志着互联|时代的开始,它能够被应用在全球信息网l的q_上编写互动性及强的AppletE序Q?995q的Applet无疑能给Z无穷的视觉和脑力震荡。我们姑且将Java的这D历史称为Java前传吧?<br /><br />  其实Java的诞生颇有那么一股“有心栽p不开Q无心插x成阴”的味道。就象当qUnix和它的前wMULTICSpȝ一栗?br /><br /><br /><img onclick="if(this.width>screen.width-461) window.open('../../.././1123517557/Fid_46/46_4677.jpg');" alt="" src="http://bbs.lupaworld.com/1123517557/Fid_46/46_4677.jpg" onload="if(this.width>screen.width-460)this.width=screen.width-460;" border="0" twffan="done" /><br /><br />  ? Java创始?James Gosling博士<br /><br />  <strong>二、JDK的幼q时?1995?998)</strong><br /><br />  SunlGreen目后又l过了几q的研究Q终于在1995q??3日在SunWorld'95上正式发布Java和HotJava览器。在同年Q有很多公司先后获得了Java许可证,如Netscape?995q?月,Oracle?995q?0月分别获得了Java许可证。Sun?995q发布第一个Java版本后,?996q?月宣布成立新的业务部门──JavaSoft部,q个部分主要负责开发、销售ƈ支持ZJava技术的产品Q由AlanBaratz先生L裁?<br /><br />  ?995qSun虽然推出了JavaQ但q只是一U语aQ而要惛_发复杂的应用E序Q必要有一个的强大的开发库支持q行。因此,Sun?996q??3日发布了JDK1.0。这个版本包括了两部分:q行环境Q即JREQ和开发环?即JDK)。在q行环境中包括了核心API、集成APIQ用L面APIQ发布技术,Java虚拟?JVM)五个部分。而开发环境还包括了编译JavaE序的编译器Q即javacQ。在JDK1.0时代QJDK除了AWTQ一U用于开发图形用L面的APIQ外Q其它的库ƈ不完整?<br /><br />  Sun在推出JDK1.0后,紧跟着QSun?997q??8日发布了JDK1.1。JDK1.1相对于JDK1.0最大的改进是为JVM增加了JIT(x~译)~译器。JIT和传l的~译器不同,传统的编译器是编译一条,q行完后再将其扔掉,而JIT会将l常用到的指令保存在内容中,在下ơ调用时׃需要再~译了。这样JDK在效率上有了非常大的提升?<br /><br />  Sun在推出JDK1.1后,接着又推ZCJDK1.x版本。自从Sun推出Java后,JDK的下载量不断彪升Q在1997q_JDK的下载量H破?20,000Q而在1998q_JDK的下载量已经过?,000,000?<br /><br />  虽然?998q之前,Java被众多的软g企业所采用Q但׃当时g环境和JVM的技术原因,它的应用却很有限。当时Java主要只用在前端的Applet以及一些移动设备中。然而这q不{于Java的应用只限于q些领域。在1998q是Java开始迅猛发展的一q。在q一q中Sun发布了JSP/Servlet、EJB规范以及Java分成了J2EE、J2SE和J2ME。标志着Java已经吹响了向企业、桌面和Ud3个领域进军的可?br /><br />  <strong>三、JDK的青年时期(1998?004)</strong><br /><br />  ?998q_Java已经走过?个年头。从JDK1.0到JDK1.1.8。JDK1.xl过?个小版本的发展,已经初具规模。至此,它已l走Z摇篮Q可以去独闯世界了?<br /><br />  ?998q?2?日。Sun发布了Java的历史上最重要的一个JDK版本QJDK1.2。这个版本标志着Java已经q入Java2时代。这个时期也是Java飞速发展的时期?<br /><br />  在Java2时代Sun对Javaq行了很多革命性的变化 Q而这些革命性的变化一直沿用到现在Q对Java的发展Ş成了p的媄响?<br /><br />  JDK1.2自从被分成了J2EE、J2SE和J2ME三大块,得到了市场的强烈反响。不仅如此,JDK1.2q对它的API分成了三大类?<br /><br />  核心API <br />  由Sun公司制定的基本的APIQ所有的Javaq_都应该提供。这是我们q_所说的Java核心cd?<br /><br />  可选API <br />  q是Sun为JDK提供的扩充APIQ这些API因^台的不同而不同?<br />?<br />  ҎAPI <br />  用于满Ҏ要求的API。如用于JCA和JCE的第三方加密cd?<br /><br />  Java2除了上述的一些改q外Q还增加了很多新的特性。其中最吸引眼球的当属Swing了。Swing是Java的另一个图形库。它不但有各式各样先q的lgQ而且q组仉格都可抽换。在Swing出现后,很快抢了AWT的风头。但Swingq不是ؓ取代AWT而存在的Q事实上Swing是徏立在AWT之上的。就象JFace是徏立在SWT之上一栗另外Java2q在多线E、集合类和非同步cM做了大量的改q?<br /><br />  从JDK1.2开始,Sun以^?q一个版本的速度推出新的JDK。在2000q??日。Sun对JDK1.2q行了重大升U。推ZJDK1.3?<br /><br />  Sun在JDK1.3中同栯行了大量的改q,主要表现在一些类库上Q如数学q算、新的Timer API{)、在JNDI接口斚w增加了一些DNS的支持、增加了JNI的支持,q得Java可以讉K本地资源了、支持XML以及使用新的Hotspot虚拟Z替了传统的虚拟机?<br /><br />  在JDK1.3时代Q相应的应用E序服务器也得到了广泛的应用Q如W一个稳定版本Tomcat3.x在这一时期得到了广泛的应用QWebLogic{商业应用服务器也渐渐被接受?<br /><br />  旉如水、生命如歌。{眼到?002q。Sun在这一q的2?3日发布了JDK历史上最为成熟的版本QJDK1.4。在q入21世纪以来Q曾l在.NETq_和Javaq_之间发生了一ơ声势浩大的C孰劣的论战,Java的主要问题就是性能?<br /><br />  因此Q这ơSun主要精力放CJava的性能上。在JDK1.4中,Sun放言要对Hotspot虚拟机的锁机制进行了改进QJDK1.4的性能有了质的飞跃。同时由于Compaq、Fujitsu?SAS?Symbian?IBM{公司的参与QJDK1.4成ؓ发展最快的一个JDK版本。到JDK1.4为止Q我们已l可以用Java实现大多数的应用了?br /><br />  <strong>四、JDK的壮q时?2004~至?</strong><br /><br />  虽然从JDK1.4开始,Java的性能有了显著的提高,但Java又面临着另一个问题,那就是复杂?<br /><br />  虽然Java是纯面向对象语言Q但它对一些高U的语言Ҏ(如泛型、增强的for语句Qƈ不支持。而且和Java相关的技术,如EJB2.xQ也׃它们的复杂而很有人问z。也许是Sun意识Cq一炏V因此,?004q?0月,Sun发布了我们期待已久的版本QJDK1.5Q同ӞSunJDK1.5改名为J2SE5.0。和JDK1.4不同QJDK1.4的主题是性能Q而J2SE5.0的主题是易用。Sun之所以将版本?.5改ؓ5.0Q就是预C着J2SE5.0较以前的J2SE版本有着很大的改q?<br /><br />  Sun不仅为J2SE5.0增加了诸如泛型、增强的for语句、可变数目参数、注?Annotations)、自动拆(unboxingQ和装箱{功能,同时Q也更新的企业规范Q如通过注释{新Ҏ改善了EJB的复杂性,q推ZEJB3.0规范。同时又针对JSP的前端界面设计而推ZJSF。这个JSFcM于ASP.NET的服务端控g。通过它可以很快地建立起复杂的JSP界面?<br /><br />  Cq年底Sun也再接再厉地推出了J2SE6.0的测试版Q预计在2007q初推出它的正式版?<br /><br />  正象J2SE6.0的开发代号“野马(MustangQ”一P我们已经隐约听到了野马的嘉。据Sun发言人透露QJ2SE6.0不仅在性能、易用性方面得C前所未有的提高,而且q提供了如脚本、全新的APIQSwing和AWT{API已经被更斎ͼ的支持。而且J2SE6.0是专为Vista而设计的Q它在Vista上将会拥有更好的性能。在推出J2SE6.0的同ӞJ2SE7.0目也已l启动?<br /><br />  在Java发展的十几年的时间里Q经历了无数的风风雨雨。现在Java已经成ؓ一U相当成熟的语言了。在q?0q的发展中,Javaq_吸引了数百万的开发者,在网l计遍及全球的今天Q更是有20亿台讑֤使用了Java技术。作为Java技术的基础QJ2SE功不可没Q让我们期望J2SE伴随Javaq_一路走好!<br /><br />  <strong>五、JDK各版的发布时间表 </strong><br /><br />  到现在ؓ止我们已l重新走了一遍Java的历史轨qV在q一部分Qؓ了有一个M的认识,让我们来看一看Java发展的时间表?Q版本号 名称 中文?发布日期Q?<br /><br />JDK 1.1.4 <br />Sparkler <br />宝石 <br />1997-09-12 <br /><br />JDK 1.1.5 <br />Pumpkin <br />南瓜 <br />1997-12-13 <br /><br />JDK 1.1.6 <br />Abigail <br />阿比盖尔--奛_?<br />1998-04-24 <br /><br />JDK 1.1.7 <br />Brutus<br />布鲁?-古罗马政d和将?<br />1998-09-28 <br /><br />JDK 1.1.8 <br />Chelsea <br />切尔?-城市?<br />1999-04-08 <br /><br />J2SE 1.2 <br />Playground <br />q动?<br />1998-12-04 <br /><br />J2SE 1.2.1 <br />none<br />?br />1999-03-30 <br /><br />J2SE 1.2.2 <br />Cricket<br />蟋蟀<br />1999-07-08 <br /><br />J2SE 1.3 <br />Kestrel <br />洲U隼 <br />2000-05-08 <br /><br />J2SE 1.3.1 <br />Ladybird <br />瓢虫 <br />2001-05-17 <br /><br />J2SE 1.4.0 <br />Merlin <br />灰背?<br />2002-02-13 <br /><br />J2SE 1.4.1 <br />grasshopper <br />p <br />2002-09-16 <br /><br />J2SE 1.4.2 <br />Mantis <br />螌 <br />2003-06-26 <br /><br />J2SE 5.0 (1.5.0) <br />Tiger <br />老虎 <br />2004-10 <br /><br />J2SE 6.0 (Beta) <br />Mustang <br />野马 <br />2006-04 <br /><br />  从这个表中我们可以看Z个非常有意思的现象Q就是JDK的每一个版本号都用一个开发代可C(是表中的中文名Q。而且从JDK1.2.2开?主要版本(?.3,1.4,5.0)都是以鸟cLZ^动物来命名的. 而它们的bug修正版本(?.2.2,1.3.1,1.4.2)都是以昆虫命名的?br /><br />  <strong>六、Java的未?0q?/strong><br /><br />  ?005q的Java One开发者大会上QJames Gosling作了题ؓ“Java技术下一?0qA献”的演讲。谈到未来Java的发展时QJames Gosling提到了有关Java软g的性能和复杂性问题。鉴于许多机器运行着大量q程的实际情况,Z对线E模型投以越来越多的x?<br /><br />  随着ZҎ面应用的要求来高Q系l将变得来复杂。他指出Q?“从工程的角度来看,未来10q内我们所面的最大挑战就是复杂性问题,?James Gosling_ “目前,我们开展了许多工作以解军_用编E接口、语a以及工具中所涉及的复杂性问题。在工具和用L?UI)中都会遇到复杂性问题,Java技术设计h员必d理好大小寸调整和国际化的问题。?<br /><br />  在这ơ大会上QJames Goslingq同Java技术先驱,CQKleiner, Perkins Caulfield and Byers合伙人的Bill Joy先生QSun公司首席U学家John Gage先生Q未来研I所MQPaul Saffo先生QSun杰出工程师Guy Steele先生以及Applied Mindes公司d及首席技术官Danny Hillis先生{一h讨了讨论Java语言的过d未来发展情况?<br /><br />  他们认ؓQJava技术提高了计算的“流动性”,如同货币的发明提高了商品的动性一栗无所不在的网l丰富了每个人的信息Q就如同可以兑换的货币生了财富一栗由于从前的|络是很慢的Q所以计被束缚在特定的计算ZQ而这U情况将一M复返了?<br /><br />  目前Q全球Java开发h员已l超q?50万,而与之相对应的是JavaC֌充满zd和创新精,q正是Java下一?0q更加繁荣的保障。ؓ了保持Java的增长和推进JavaC֌的参? Sun在Java One开发者大会上宣布开放Java核心源代码,以鼓励更多的人参与到C֛zd中来Q这是Sun为推q社团发展和l护Java技术兼Ҏ而迈出的重要一步?<br /><br />  Sun公司总裁兼首席运营官Jonathan Schwartz先生指出Q来自JavaC֛和IBM{全球技术合作伙伴两斚w的支持,乃是Java技术在创新和社会进步上l箋发挥重要作用的强有力的标志。技术开攑֒C֛降低了技术应用的壁垒Q其l果是ؓ参与和增长创造了更多的商机,q就形成了hg千亿元的Java产业?<br /><br />  有很多h认ؓJava开源后Q在众多开发h员的参与之下QJava会变得更加强大。随着Java和IT业界的关pd得更加紧密,Sun公司也将更容易卖己兼容Java良好的WEB服务器和操作pȝ。这个D动将会给软g开发群体带来新的活力,改善Sun公司的公众Ş象,q同时证明Sun可以成ؓ一个开源社会的“良民”?<br /><br />  随着Java的开源,Java的未来似乎变得更加明朗。在未来QJava的应用范围有可能变得更广。Sun董事镉K克里在2006q的JavaOne会议上说Q“全球有3/4的hq不能接入InternetQ这对Java技术伙伴来说是一个巨大的l济Z。瘦客户机、微的传感器以及其它Java驱动的小装置Q可以帮助我们改善h们的生活。他希望JavaC֌通过他们的工作能够I合数字`沟”?<br /><br />  Sun认ؓQ数字媒体将是Java的下一个重点市场,同时Q教育和健康是未来Java发展q程中的两大重点应用领域。但愿Java的未来真能象Sun宣称的那P成ؓ我们未来生活的一部分?img src ="http://www.aygfsteel.com/chenlb/aggbug/89974.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.aygfsteel.com/chenlb/" target="_blank">浪?/a> 2006-12-25 20:30 <a href="http://www.aygfsteel.com/chenlb/articles/89974.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MD5http://www.aygfsteel.com/chenlb/articles/83367.html浪?/dc:creator>浪?/author>Fri, 24 Nov 2006 13:12:00 GMThttp://www.aygfsteel.com/chenlb/articles/83367.htmlhttp://www.aygfsteel.com/chenlb/comments/83367.htmlhttp://www.aygfsteel.com/chenlb/articles/83367.html#Feedback0http://www.aygfsteel.com/chenlb/comments/commentRss/83367.htmlhttp://www.aygfsteel.com/chenlb/services/trackbacks/83367.html阅读全文

]]>
单的d文ghttp://www.aygfsteel.com/chenlb/articles/80586.html浪?/dc:creator>浪?/author>Sat, 11 Nov 2006 07:40:00 GMThttp://www.aygfsteel.com/chenlb/articles/80586.htmlhttp://www.aygfsteel.com/chenlb/comments/80586.htmlhttp://www.aygfsteel.com/chenlb/articles/80586.html#Feedback0http://www.aygfsteel.com/chenlb/comments/commentRss/80586.htmlhttp://www.aygfsteel.com/chenlb/services/trackbacks/80586.html 



import  java.io.File;
import  java.io.FileInputStream;
import  java.io.FileNotFoundException;
import  java.io.IOException;
import  java.nio.ByteBuffer;
import  java.nio.channels.FileChannel;


public   class  ReadAString  {

    
/**
     * 
@param  args
     
*/

    
public   static   void  main(String[] args)  {
        
//  TODO 自动生成Ҏ存根

        File aFile 
=   new  File( " d:/test.txt " );
        FileInputStream inFile 
=   null ;
        
        
try   {
            inFile 
=   new  FileInputStream(aFile);
        }
  catch (FileNotFoundException e)  {
            e.printStackTrace(System.err);
            System.exit(
1 );
        }

        
        FileChannel inChannel 
=  inFile.getChannel();
        ByteBuffer buf 
=  ByteBuffer.allocate( 48 );
        
// String buf = "";
         try   {
            
while (inChannel.read(buf)  !=   - 1 {
                System.out.println(
" String read:  " +
                        ((ByteBuffer)(buf.flip())).asCharBuffer().toString());
                buf.clear();
            }

            System.out.println(
" EOF readched. " );
            inFile.close();
        }
  catch (IOException e)  {
            e.printStackTrace(System.err);
            System.exit(
1 );
        }

        
        System.exit(
0 );
    }


}



]]>
վ֩ģ壺 ɽ| Ϫ| ƽ| | ¡Ң| ɽ| Ƹ| կ| ʯ| | | ϲ| ֦| ʯ| ͨ| | ƽ| ɽʡ| ٺ| | | ٤ʦ| | | ƽ| Ҧ| Ӻ| | ͭ| | ̨ʡ| ɽ| | | | | | | | ˷| ¸|