﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>语源科技BlogJava-JOY工作室---Java</title><link>http://www.blogjava.net/wuhen86/</link><description>Jump Over yourself !</description><language>zh-cn</language><lastBuildDate>Mon, 13 Apr 2026 09:00:17 GMT</lastBuildDate><pubDate>Mon, 13 Apr 2026 09:00:17 GMT</pubDate><ttl>60</ttl><item><title>JAVA中的反射机制</title><link>http://www.blogjava.net/wuhen86/articles/355219.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Thu, 28 Jul 2011 05:45:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/355219.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/355219.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/355219.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/355219.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/355219.html</trackback:ping><description><![CDATA[<p>JAVA反射机制是在运行状态中，对于任意一个类，都能够知道这个类的所有属性和方法；对于任意一个对象，都能够调用它的任意一个方法；这种动态获取的信息以及动态调用对象的方法的功能称为java语言的反射机制。   <br />Java反射机制主要提供了以下功能： 在运行时分析类的能力，判断任意对象所属类，类中有哪些方法，有哪些成员变量；在运行时控查对象，比如，只写一个toString()方法供所有的类使用；实现通用数组操作代码的功能。</p>  <p>1. 得到某个对象的属性   <br />1 public Object getProperty(Object owner, String fieldName) throws Exception {    <br />2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class ownerClass = owner.getClass();    <br />3    <br />4&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Field field = ownerClass.getField(fieldName);    <br />5    <br />6&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object property = field.get(owner);    <br />7    <br />8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return property;    <br />9 }    <br />Class ownerClass = owner.getClass()：得到该对象的Class。    <br />Field field = ownerClass.getField(fieldName)：通过Class得到类声明的属性。    <br />Object property = field.get(owner)：通过对象得到该属性的实例，如果这个属性是非公有的，这里会报IllegalAccessException。    <br />2. 得到某个类的静态属性    <br />1 public Object getStaticProperty(String className, String fieldName)    <br />2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; throws Exception {    <br />3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class ownerClass = Class.forName(className);    <br />4    <br />5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Field field = ownerClass.getField(fieldName);    <br />6    <br />7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object property = field.get(ownerClass);    <br />8    <br />9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return property;    <br />10 }    <br />Class ownerClass = Class.forName(className) ：首先得到这个类的Class。    <br />Field field = ownerClass.getField(fieldName)：和上面一样，通过Class得到类声明的属性。    <br />Object property = field.get(ownerClass) ：这里和上面有些不同，因为该属性是静态的，所以直接从类的Class里取。    <br />3. 执行某对象的方法    <br />1 public Object invokeMethod(Object owner, String methodName, Object[] args) throws Exception {    <br />2    <br />3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class ownerClass = owner.getClass();    <br />4    <br />5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class[] argsClass = new Class[args.length];    <br />6    <br />7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0, j = args.length; i &lt; j; i++) {    <br />8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; argsClass[i] = args[i].getClass();    <br />9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }    <br />10    <br />11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method method = ownerClass.getMethod(methodName, argsClass);    <br />12    <br />13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return method.invoke(owner, args);    <br />14 }    <br />Class owner_class = owner.getClass() ：首先还是必须得到这个对象的Class。    <br />5～9行：配置参数的Class数组，作为寻找Method的条件。    <br />Method method = ownerClass.getMethod(methodName, argsClass)：通过Method名和参数的Class数组得到要执行的Method。    <br />method.invoke(owner, args)：执行该Method，invoke方法的参数是执行这个方法的对象，和参数数组。返回值是Object，也既是该方法的返回值。    <br />4. 执行某个类的静态方法    <br />1 public Object invokeStaticMethod(String className, String methodName,    <br />2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Object[] args) throws Exception {    <br />3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class ownerClass = Class.forName(className);    <br />4    <br />5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class[] argsClass = new Class[args.length];    <br />6    <br />7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0, j = args.length; i &lt; j; i++) {    <br />8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; argsClass[i] = args[i].getClass();    <br />9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }    <br />10    <br />11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Method method = ownerClass.getMethod(methodName, argsClass);    <br />12    <br />13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return method.invoke(null, args);    <br />14 }    <br />基本的原理和实例3相同，不同点是最后一行，invoke的一个参数是null，因为这是静态方法，不需要借助实例运行。    <br />5. 新建实例    <br />1    <br />2 public Object newInstance(String className, Object[] args) throws Exception {    <br />3&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class newoneClass = Class.forName(className);    <br />4    <br />5&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class[] argsClass = new Class[args.length];    <br />6    <br />7&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (int i = 0, j = args.length; i &lt; j; i++) {    <br />8&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; argsClass[i] = args[i].getClass();    <br />9&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }    <br />10    <br />11&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Constructor cons = newoneClass.getConstructor(argsClass);    <br />12    <br />13&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return cons.newInstance(args);    <br />14    <br />15 }    <br />这里说的方法是执行带参数的构造函数来新建实例的方法。如果不需要参数，可以直接使用newoneClass.newInstance()来实现。    <br />Class newoneClass = Class.forName(className)：第一步，得到要构造的实例的Class。    <br />第5～第9行：得到参数的Class数组。    <br />Constructor cons = newoneClass.getConstructor(argsClass)：得到构造子。    <br />cons.newInstance(args)：新建实例。    <br />6. 判断是否为某个类的实例    <br />1 public boolean isInstance(Object obj, Class cls) {    <br />2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return cls.isInstance(obj);    <br />3 }    <br />7. 得到数组中的某个元素    <br />1 public Object getByArray(Object array, int index) {    <br />2&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return Array.get(array,index);    <br />3 }    <br />其中，反射机制最重要的部分是允许你检查类的结构。java.lang.reflect包中的三个类Field,Method,Constructor类分别描述类的字段，方法和构造器，它们都有一个getName方法，用来返回相应条目的名称。</p><img src ="http://www.blogjava.net/wuhen86/aggbug/355219.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-07-28 13:45 <a href="http://www.blogjava.net/wuhen86/articles/355219.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>java中读取配置文件信息的六种方法</title><link>http://www.blogjava.net/wuhen86/articles/355218.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Thu, 28 Jul 2011 05:34:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/355218.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/355218.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/355218.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/355218.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/355218.html</trackback:ping><description><![CDATA[<p>1。使用Java.util.Properties类的load()方法<br />示例： InputStream in = lnew BufferedInputStream(new FileInputStream(name));<br />Properties p = new Properties();<br />p.load(in);  </p><p>2。使用java.util.ResourceBundle类的getBundle()方法<br />示例： ResourceBundle rb = ResourceBundle.getBundle(name, Locale.getDefault());  </p><p>3。使用java.util.PropertyResourceBundle类的构造函数<br />示例： InputStream in = new BufferedInputStream(new FileInputStream(name));<br />ResourceBundle rb = new PropertyResourceBundle(in);  </p><p>4。使用class变量的getResourceAsStream()方法<br />示例： InputStream in = JProperties.class.getResourceAsStream(name);<br />Properties p = new Properties();<br />p.load(in);  </p><p>5。使用class.getClassLoader()所得到的java.lang.ClassLoader的getResourceAsStream()方法<br />示例： InputStream in = JProperties.class.getClassLoader().getResourceAsStream(name);<br />Properties p = new Properties();<br />p.load(in);  </p><p>6。使用java.lang.ClassLoader类的getSystemResourceAsStream()静态方法</p><img src ="http://www.blogjava.net/wuhen86/aggbug/355218.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-07-28 13:34 <a href="http://www.blogjava.net/wuhen86/articles/355218.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JAVA深入探索－参数传递</title><link>http://www.blogjava.net/wuhen86/articles/355216.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Thu, 28 Jul 2011 05:31:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/355216.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/355216.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/355216.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/355216.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/355216.html</trackback:ping><description><![CDATA[<p><strong>按值传参<br /></strong>JAVA中的参数传递只存在传值方式一种，但也有传引用的概念。<br />这是java参数传递的核心说明。java不像C/C＋＋那样可以通过指针符或地址符来区分传值还是传引用，因为它只有一种参数传递的方式，那就是传值方式。这对初学java的人来说很难理解，通过下面的例子可以看出真正的传值在java中是如何实现的。<br />public static void swap(int a,int b){//交换两个变量的值<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int temp = a;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a = b;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; b = temp;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println("swap:"+a+","+b);<br />}<br />......<br />&nbsp;&nbsp;&nbsp; int a = 3;<br />int b = 5;<br />&nbsp;&nbsp; swap(a,b);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(a +" "+b);//3 5<br />......<br />程序打印结果：<br />swap:5,3<br />3&nbsp;&nbsp; 5<br />由程序的结果可以看到，事实上，经过交换的方法swap()之后，主程序中的变量a,b的值并没有被改变。<br />分析过程如下：在调用swap()方法的时候，程序把a、b的副本送到swap()方法中的变量a、b中去，而主程序中的变量a、b中的内容并没有被改变。所以就会出现上面的结果。<br />其实，不仅是简单的数据类型如此 ，如果传递的参数是一个对象，也会出现这样的结果，这与简单数据类型的情况类似，都可以划为按值传参一类中。我们看下面的程序及其分析过程：<br />public class User{<br />static void swap(User user1,User user2){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User user = user1;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; user1 = user2;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; user2 = user;<br />}<br />public static void main(String[]args){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User user3 = new User("ding", 20);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User user4 = new User("zhao", 18);<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; swap(user3, user4);&nbsp;&nbsp; <br />&nbsp;&nbsp; /*进行函数swap(user1,user2)的调用，但是并不会真正把user3和user4所指向的内存空间<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *进行交换，只是在调用的时候，会把user3中存放的内存地址复制一份传给user1,把user4中存放的<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *内存地址复制一份传给user2，相当于只是给user1和user2了一个副本，而真正的对象<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *user3和user4并没有在swap()函数中被触及。所以函数处理的结果是使user1和user2所指向的内存空间<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *进行交换，而user3和user4中的存放内容仍是原来的内容。*/<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(user3.username + "&nbsp;&nbsp; " +user3.age);//ding&nbsp;&nbsp; 20<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(user4.username + "&nbsp;&nbsp; " +user4.age);//zhao&nbsp;&nbsp; 18<br />｝<br />程序的运行结果：<br />ding&nbsp;&nbsp; 20<br />zhao&nbsp;&nbsp; 18 </p><p><strong>传递引用</strong><br />既然说java中的参数传递只有by value一种，为什么还要说传递引用呢？实际上，java与C＋＋一样，同样存在对一个对象的引用进行传递的问题，但java中的引用传递机制是，把原来变量中保存的内存地址传递作为一个参数进行传递，而不是直接把引用传过去。所以在java中仍把它称做按值传参。<br />同样采用例子的方式来解释java中的引用传递的问题:<br />.......<br />public static&nbsp;&nbsp; void changAge(User user){<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User temp = user;//这时，temp中存放了和原对象相同的内存地址<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; temp.age = temp.age + 20;//对user的年龄进行增加的操作，<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*是对temp所指向的内存空间中的值直接进行操作，所以会对原对象的值造成影响。就相当于是传递了原对象的引用*/<br />}<br />......<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; User user = new User("li",25);//仍采用上例中的User<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; changAge(user);//改变user的年龄<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.out.println(user.age);//45<br />.......<br />有了上面例子的说明，我们可能就会想到，如果我们的程序中私有变量是一个对象类型的变量时，在主程序中有了这个私有变量的拷贝，是不是就有可能在修改这个拷贝时不小心把原来的私有变量的值也给改变了呢？<br />我们来看下面的例子：<br />class Test{<br />private Date date=new Date();<br />public Date getDate(){<br />return date;<br />}<br />public static void main(String[] args){<br />Test tt=new Test();<br />Date myDate=tt.getDate();//返回了一个私有变量的拷贝<br />System.out.println(myDate);<br />myDate.setTime(new Date().getTime()-(long)(10*365.25*24*3600*1000));//对新产生的拷贝进行修改<br />System.out.println(tt.getDate());<br />System.out.println(myDate);<br />}<br />}<br />先来猜一下运行的结果,是前两句输出一样呢还是后两句输出一样(最后一句输出比第一句输出的日期早十年)?很多人都会说是前两句输出一样.实际上,你会惊奇地发现，输出结果显示后两者输出一样，私有变量在程序外部被改变了，程序的封装性遭到了破坏。<br />出错的原因很微妙.因为myDate和tt指向了同一个对象，对myDate的引用更改方法自动地改变了这个类的私有方法状态。经过测试可以知道，如果myDate被重新赋值（比如myDate=new Date())，就不会出现上面的结果。但是现在的这个程序，私有变量还是在程序外部被改变了。<br />如果需要返回一个指向可变对象的引用，我们就需要克隆它，这样就不会导致上面的私有变量被更改。<br />上面程序就应更改为：return (Date)date.clone();就可以<strong>防止私有变量被修改</strong>的麻烦了。<br />再来执行上面的程序，就会出现不一样的结果。</p><img src ="http://www.blogjava.net/wuhen86/aggbug/355216.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-07-28 13:31 <a href="http://www.blogjava.net/wuhen86/articles/355216.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>使用JNI技术实现JAVA程序调用dll</title><link>http://www.blogjava.net/wuhen86/articles/355212.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Thu, 28 Jul 2011 04:37:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/355212.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/355212.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/355212.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/355212.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/355212.html</trackback:ping><description><![CDATA[<p>JAVA的跨平台的特性深受java程序员们的喜爱,但正是由于它为了实现跨平台的目的,使得它和本地机器的各种内部联系变得很少,大大约束了它的功能,比如与一些硬件设备通信,往往要花费很大的精力去设计流程编写代码去管理设备端口,而且有一些设备厂商提供的硬件接口已经经过一定的封装和处理,不能直接使用java程序通过端口和设备通信,这种情况下就得考虑使用java程序去调用比较擅长同系统打交道的第三方程序,从1.1版本开始的JDK提供了解决这个问题的技术标准:JNI技术.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; JNI是Java Native Interface(Java本地接口)的缩写,本地是相对于java程序来说的,指直接运行在操作系统之上,与操作系统直接交互的程序.从1.1版本的JDK开始,JNI就作为标准平台的一部分发行.在JNI出现的初期是为了Java程序与本地已编译语言,尤其是C和C++的互操作而设计的,后来经过扩展也可以与c和c++之外的语言编写的程序交互,例如Delphi程序.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 使用JNI技术固然增强了java程序的性能和功能,但是它也破坏了java的跨平台的优点,影响程序的可移植性和安全性,例如由于其他语言(如C/C++)可能能够随意地分配对象/占用内存,Java的指针安全性得不到保证.但在有些情况下,使用JNI是可以接受的,甚至是必须的,例如上面提到的使用java程序调用硬件厂商提供的类库同设备通信等,目前市场上的许多读卡器设备就是这种情况.在这必须使用JNI的情况下,尽量把所有本地方法都封装在单个类中,这个类调用单个的本地库文件,并保证对于每种目标操作系统,都可以用特定于适当平台的版本替换这个文件,这样使用JNI得到的要比失去的多很多.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 现在开始讨论上面提到的问题,一般设备商会提供两种类型的类库文件,windows系统的会包含.dll/.h/.lib文件,而linux系统的会包含.so/.a文件,这里只讨论windows系统下的c/c++编译的dll文件调用方法.<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我把设备商提供的dll文件称之为第三方dll文件,之所以说第三方,是因为JNI直接调用的是按它的标准使用c/c++语言编译的dll文件,这个文件是客户程序员按照设备商提供的.h文件中的列出的方法编写的dll文件,我称之为第二方dll文件,真正调用设备商提供的dll文件的其实就是这个第二方dll文件.到这里,解决问题的思路已经产生了,大慨分可以分为三步:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1&gt;编写一个java类,这个类包含的方法是按照设备商提供的.h文件经过变形/转换处理过的,并且必须使用native定义.这个地方需要注意的问题是java程序中定义的方法不必追求和厂商提供的头文件列出的方法清单中的方法具有相同的名字/返回值/参数,因为一些参数类型如指针等在java中没法模拟,只要能保证这个方法能实现原dll文件中的方法提供的功能就行了;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2&gt;按JNI的规则使用c/c++语言编写一个dll程序;<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3&gt;按dll调用dll的规则在自己编写的dll程序里面调用厂商提供的dll程序中定义的方法.  </p><p>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 我之前为了给一个java项目添加IC卡读写功能,曾经查了很多资料发现查到的资料都是只说到第二步,所以剩下的就只好自己动手研究了.下面结合具体的代码来按这三个步骤分析.  </p><p>&nbsp;&nbsp;&nbsp;&nbsp; 1&gt;假设厂商提供的.h文件中定义了一个我们需要的方法:<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; __int16 __stdcall readData( HANDLE icdev, __int16 offset, __int16 len, unsigned char *data_buffer );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; a.__int16定义了一个不依赖于具体的硬件和软件环境,在任何环境下都占16 bit的整型数据(java中的int类型是32 bit),这个数据类型是vc++中特定的数据类型,所以我自己做的dll也是用的vc++来编译.<br />&nbsp;&nbsp;&nbsp;&nbsp; b.__stdcall表示这个函数可以被其它程序调用,vc++编译的DLL欲被其他语言编写的程序调用,应将函数的调用方式声明为__stdcall方式,WINAPI都采用这种方式.c/c++语言默认的调用方式是__cdecl,所以在自己做可被java程序调用的dll时一定要加上__stdcall的声明,否则在java程序执行时会报类型不匹配的错误.<br />&nbsp;&nbsp;&nbsp;&nbsp; c.HANDLE icdev是windows操作系统中的一个概念,属于win32的一种数据类型,代表一个核心对象在某一个进程中的唯一索引,不是指针,在知道这个索引代表的对象类型时可以强制转换成此类型的数据.<br />&nbsp;&nbsp;&nbsp; 这些知识都属于win32编程的范围,更为详细的win32资料可以查阅相关的文档.<br />&nbsp;&nbsp;&nbsp; 这个方法的原始含义是通过设备初始时产生的设备标志号icdev,读取从某字符串在内存空间中的相对超始位置offset开始的共len个字符,并存放到data_buffer指向的无符号字符类型的内存空间中,并返回一个16 bit的整型值来标志这次的读设备是否成功,这里真正需要的是unsigned char *这个指针指向的地址存放的数据,而java中没有指针类型,所以可以考虑定义一个返回字符串类型的java方法,原方法中返回的整型值也可以按经过一定的规则处理按字符串类型传出,由于HANDLE是一个类型于java中的Ojbect类型的数据,可以把它当作int类型处理,这样java程序中的方法定义就已经形成了:<br />&nbsp;&nbsp;&nbsp; String readData( int icdev, int offset, int len );<br />&nbsp;&nbsp;&nbsp; 声明这个方法的时候要加上native关键字,表明这是一个与本地方法通信的java方法,同时为了安全起见,此文方法要对其它类隐藏,使用private声明,再另外写一个public方法去调用它,同时要在这个类中把本地文件加载进来,最终的代码如下:  </p><p>package test;  </p><p>public class LinkDll<br />{<br />&nbsp;&nbsp;&nbsp; //从指定地址读数据<br />&nbsp;&nbsp;&nbsp; private native String readData( int icdev, int offset, int len );<br />&nbsp;&nbsp;&nbsp; public String readData( int icdev, int offset, int len )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return this.readDataTemp( icdev, offset, len );<br />&nbsp;&nbsp;&nbsp; }  </p><p>&nbsp;&nbsp;&nbsp; static&nbsp; <br />&nbsp;&nbsp;&nbsp; {&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; System.loadLibrary( "TestDll" );//如果执行环境是linux这里加载的是SO文件,如果是windows环境这里加载的是dll文件<br />&nbsp;&nbsp;&nbsp; }<br />}  </p><p>2&gt;使用JDK的javah命令为这个类生成一个包含类中的方法定义的.h文件,可进入到class文件包的根目录下(只要是在classpath参数中的路径即可),使用javah命令的时候要加上包名javah test.LinkDll,命令成功后生成一个名为test_LinkDll.h的头文件.<br />&nbsp;&nbsp;&nbsp; 文件内容如下:  </p><p>/* DO NOT EDIT THIS FILE - it is machine generated*/<br />#include &lt;jni.h&gt;  </p><p>/* Header for class test_LinkDll */<br />#ifndef _Included_test_LinkDll #define  </p><p>Included_test_LinkDll<br />#ifdef __cplusplus extern "C" { #endif<br />/*<br />* Class:&nbsp;&nbsp;&nbsp;&nbsp; test_LinkDll<br />* Method:&nbsp;&nbsp;&nbsp; readDataTemp<br />* Signature: (III)Ljava/lang/String;<br />*/<br />JNIEXPORT jstring JNICALL Java_test_LinkDll_readDataTemp(JNIEnv *, jobject, jint, jint, jint);<br />#ifdef __cplusplus } #endif<br />#endif  </p><p>&nbsp;&nbsp;&nbsp; 可以看出,JNI为了实现和dll文件的通信,已经按它的标准对方法名/参数类型/参数数目作了一定的处理,其中的JNIEnv*/jobjtct这两个参数是每个JNI方法固有的参数,javah命令负责按JNI标准为每个java方法加上这两个参数.JNIEnv是指向类型为JNIEnv_的一个特殊JNI数据结构的指针,当由C++编译器编译时JNIEnv_结构其实被定义为一个类,这个类中定义了很多内嵌函数,通过使用"-&gt;"符号,可以很方便使用这些函数,如:<br />&nbsp;&nbsp;&nbsp; (env)-&gt;NewString( jchar* c, jint len )<br />&nbsp;&nbsp;&nbsp; 可以从指针c指向的地址开始读取len个字符封装成一个JString类型的数据.<br />&nbsp;&nbsp;&nbsp; 其中的jchar对应于c/c++中的char,jint对应于c/c++中的len,JString对应于java中的String,通过查看jni.h可以看到这些数据类型其实都是根据java和c/c++中的数据类型对应关系使用typedef关键字重新定义的基本数据类型或结构体.<br />&nbsp;&nbsp;&nbsp; 具体的对应关系如下:<br />Java类型&nbsp;&nbsp;&nbsp;&nbsp; 本地类型&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 描述<br />boolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jboolean&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++8位整型<br />byte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jbyte&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++带符号的8位整型<br />char&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jchar&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++无符号的16位整型<br />short&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jshort&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++带符号的16位整型<br />int&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jint&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++带符号的32位整型<br />long&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jlong&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++带符号的64位整型e<br />float&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jfloat&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++32位浮点型<br />double&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jdouble&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; C/C++64位浮点型<br />Object&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobject&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 任何Java对象,或者没有对应java类型的对象<br />Class&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jclass&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Class对象<br />String&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jstring&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 字符串对象<br />Object[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jobjectArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 任何对象的数组<br />boolean[]&nbsp;&nbsp;&nbsp; jbooleanArray&nbsp;&nbsp;&nbsp;&nbsp; 布尔型数组<br />byte[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jbyteArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 比特型数组<br />char[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jcharArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 字符型数组<br />short[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jshortArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 短整型数组<br />int[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jintArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 整型数组<br />long[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jlongArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 长整型数组<br />float[]&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jfloatArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 浮点型数组<br />double[]&nbsp;&nbsp;&nbsp;&nbsp; jdoubleArray&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 双浮点型数组<br />&nbsp;&nbsp;&nbsp; 更为详细的资料可以查阅JNI文档.<br />&nbsp;&nbsp;&nbsp; 需要注意的问题:test_LinkDll.h文件包含了jni.h文件;  </p><p>3&gt;使用vc++ 6.0编写TestDll.dll文件,这个文件名是和java类中loadLibrary的名称一致.<br />a&gt;使用vc++6.0 新建一个Win32 Dynamic-Link Library的工程文件,工程名指定为TestDll<br />b&gt;把源代码文件和头文件使用"Add Fiels to Project"菜单加载到工程中,若使用c来编码,源码文件后缀名为.c,若使用c++来编码,源码文件扩展名为.cpp,这个一定要搞清楚,因为对于不同的语言,使用JNIEnv指针的方式是不同的.<br />c&gt;在这个文件里调用设备商提供的dll文件,设备商一般提供三种文件:dll/lib/h,这里假设分别为A.dll/A.lib/A.h.<br />这个地方的调用分为动态调用和静态调用静态调用即是只要把被调用的dll文件放到path路径下,然后加载lib链接文件和.h头文件即可直接调用A.dll中的方法:<br />把设备商提供的A.h文件使用"Add Fiels to Project"菜单加载到这个工程中,同时在源代码文件中要把这个A.h文件使用include包含进来;<br />然后依次点击"Project-&gt;settings"菜单,打开link选项卡,把A.lib添加到"Object/library modules"选项中.<br />具体的代码如下:<br />//读出数据,需要注意的是如果是c程序在调用JNI函数时必须在JNIEnv的变量名前加*,如(*env)-&gt;xxx,如果是c++程序,则直接使用(env)-&gt;xxx  </p><p>#include&lt;WINDOWS.H&gt;<br />#include&lt;MALLOC.H&gt;<br />#include&lt;STDIO.H&gt;<br />#include&lt;jni.h&gt;<br />#include "test_LinkDll.h"<br />#include "A.h"  </p><p>JNIEXPORT jstring JNICALL Java_test_LinkDll_readDataTemp( JNIEnv *env, jobject jo, jint ji_icdev, jint ji_len )<br />{<br />&nbsp;&nbsp;&nbsp; //*************************基本数据声明与定义******************************<br />&nbsp;&nbsp;&nbsp;&nbsp; HANDLE H_icdev = (HANDLE)ji_icdev;//设备标志符<br />&nbsp;&nbsp;&nbsp; __int16 i16_len = (__int16)ji_len;//读出的数据长度,值为3,即3个HEX形式的字符<br />&nbsp;&nbsp;&nbsp; __int16 i16_result;//函数返回值<br />&nbsp;&nbsp;&nbsp; __int16 i16_coverResult;//字符转换函数的返回值<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i_temp;//用于循环的中间变量<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jchar jca_result[3] = { 'e', 'r', 'r' };//当读数据错误时返回此字符串  </p><p>&nbsp;&nbsp;&nbsp; //无符号字符指针,指向的内存空间用于存放读出的HEX形式的数据字符串<br />&nbsp;&nbsp;&nbsp; unsigned char* uncp_hex_passward = (unsigned char*)malloc( i16_len );<br />&nbsp;&nbsp;&nbsp; //无符号字符指针,指向的内存空间存放从HEX形式转换为ASC形式的数据字符串<br />&nbsp;&nbsp;&nbsp; unsigned char* uncp_asc_passward = (unsigned char*)malloc( i16_len * 2 );<br />&nbsp;&nbsp;&nbsp; //java char指针,指向的内存空间存放从存放ASC形式数据字符串空间读出的数据字符串<br />&nbsp;&nbsp;&nbsp; jchar *jcp_data = (jchar*)malloc(i16_len*2+1);<br />&nbsp;&nbsp;&nbsp; //java String,存放从java char数组生成的String字符串,并返回给调用者<br />&nbsp;&nbsp;&nbsp; jstring js_data = 0;  </p><p>&nbsp;&nbsp;&nbsp; //*********读出3个HEX形式的数据字符到uncp_hex_data指定的内存空间**********<br />&nbsp;&nbsp;&nbsp; i16_result = readData( H_icdev, 6, uncp_hex_data );//这里直接调用的是设备商提供的原型方法.  </p><p>&nbsp;&nbsp;&nbsp; if ( i16_result != 0 )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf( "读卡错误......\n" );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //这个地方调用JNI定义的方法NewString(jchar*,jint),把jchar字符串转换为JString类型数据,返回到java程序中即是String<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (env)-&gt;NewString( jca_result, 3 );<br />&nbsp;&nbsp;&nbsp; }  </p><p>&nbsp;&nbsp;&nbsp; printf( "读数据成功......\n" );  </p><p>&nbsp;&nbsp;&nbsp; //**************HEX形式的数据字符串转换为ASC形式的数据字符串**************<br />&nbsp;&nbsp;&nbsp; i16_coverResult = hex_asc( uncp_hex_data, uncp_asc_data, 3 );<br />&nbsp;&nbsp;&nbsp; if ( i16_coverResult != 0 )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf( "字符转换错误！\n" );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (env)-&gt;NewString( jca_result, 3 );<br />&nbsp;&nbsp;&nbsp; }  </p><p>&nbsp;&nbsp;&nbsp; //**********ASC char形式的数据字符串转换为jchar形式的数据字符串***********<br />&nbsp;&nbsp;&nbsp; for ( i_temp = 0; i_temp &lt; i16_len; i_temp++ )&nbsp; <br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jcp_data[i_temp] = uncp_hex_data[i_temp];<br />&nbsp;&nbsp;&nbsp; //******************jchar形式的数据字符串转换为java String****************<br />&nbsp;&nbsp;&nbsp; js_data = (env)-&gt;NewString(jcp_data,i16_len);&nbsp; <br />&nbsp;&nbsp;&nbsp; return js_data;<br />}  </p><p>动态调用,不需要lib文件,直接加载A.dll文件,并把其中的文件再次声明,代码如下:<br />#include&lt;STDIO.H&gt;<br />#include&lt;WINDOWS.H&gt;<br />#include "test_LinkDll.h"  </p><p>//首先声明一个临时方法,这个方法名可以随意定义,但参数同设备商提供的原型方法的参数保持一致.<br />typedef int ( *readDataTemp )( int, int, int, unsigned char * );//从指定地址读数据  </p><p>//从指定地址读数据<br />JNIEXPORT jstring JNICALL Java_readDataTemp( JNIEnv *env, jobject jo, jint ji_icdev, jint ji_offset, jint ji_len )<br />{<br />&nbsp;&nbsp;&nbsp; int i_temp;<br />&nbsp;&nbsp;&nbsp; int i_result;<br />&nbsp;&nbsp;&nbsp; int i_icdev = (int)ji_icdev;<br />&nbsp;&nbsp;&nbsp; int i_offset = (int)ji_offset;<br />&nbsp;&nbsp;&nbsp; int i_len = (int)ji_len;<br />&nbsp;&nbsp;&nbsp; jchar jca_result[5] = { 'e', 'r', 'r' };<br />&nbsp;&nbsp;&nbsp; unsigned char *uncp_data = (unsigned char*)malloc(i_len);<br />&nbsp;&nbsp;&nbsp; jchar *jcp_data = (jchar *)malloc(i_len);<br />&nbsp;&nbsp;&nbsp; jstring js_data = 0;<br />&nbsp;&nbsp;&nbsp; //HINSTANCE是win32中同HANDLE类似的一种数据类型,意为Handle to an instance,常用来标记App实例,在这个地方首先把A.dll加载到内存空间,以一个App的形式存放,然后取  </p><p>得它的instance交给dllhandle,以备其它资源使用.<br />&nbsp;&nbsp;&nbsp; HINSTANCE dllhandle;<br />&nbsp;&nbsp;&nbsp; dllhandle = LoadLibrary( "A.dll" );<br />&nbsp;&nbsp;&nbsp; //这个地方首先定义一个已声明过的临时方法,此临时方法相当于一个结构体,它和设备商提供的原型方法具有相同的参数结构,可互相转换<br />&nbsp;&nbsp;&nbsp; readDataTemp readData;  </p><p>&nbsp;&nbsp;&nbsp; //使用win32的GetProcAddress方法取得A.dll中定义的名为readData的方法,并把这个方法转换为已被定义好的同结构的临时方法,<br />&nbsp;&nbsp;&nbsp; //然后在下面的程序中,就可以使用这个临时方法了,使用这个临时方法在这时等同于使用A.dll中的原型方法.<br />&nbsp;&nbsp;&nbsp; readData = (readDataTemp) GetProcAddress( dllhandle, "readData" );  </p><p>&nbsp;&nbsp;&nbsp; i_result = (*readData)( i_icdev, i_offset, i_len, uncp_data );  </p><p>&nbsp;&nbsp;&nbsp; if ( i_result != 0 )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printf( "读数据失败......\n" );<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return (env)-&gt;NewString( jca_result, 3 );<br />&nbsp;&nbsp;&nbsp; }  </p><p>&nbsp;&nbsp;&nbsp; for ( i_temp = 0; i_temp &lt; i_len; i_temp++ )<br />&nbsp;&nbsp;&nbsp; {<br />&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; jcp_data[i_temp] = uncp_data[i_temp];<br />&nbsp;&nbsp;&nbsp; }  </p><p>&nbsp;&nbsp;&nbsp; js_data = (env)-&gt;NewString( jcp_data, i_len );  </p><p>&nbsp;&nbsp;&nbsp; return js_data;<br />}  </p><p>4&gt;以上即是一个java程序调用第三方dll文件的完整过程,当然,在整个过程的工作全部完成以后,就可以使用java类LinkDll中的public String radData( int, int, int )方法了,效果同直接使用c/c++调用这个设备商提供的A.dll文件中的readData方法几乎一样.  </p><p>总结:JNI技术确实是提高了java程序的执行效率,并且扩展了java程序的功能,但它也确确实实破坏了java程序的最重要的优点:平台无关性,所以除非必须(不得不)使用JNI技术,一般还是提倡写100%纯java的程序.根据自己的经验及查阅的一些资料,把可以使用JNI技术的情况罗列如下:<br />&nbsp;&nbsp;&nbsp; 1&gt;需要直接操作物理设备,而没有相关的驱动程序,这时候我们可能需要用C甚至汇编语言来编写该设备的驱动,然后通过JNI调用;<br />&nbsp;&nbsp;&nbsp; 2&gt;涉及大量数学运算的部分,用java会带来些效率上的损失;<br />&nbsp;&nbsp;&nbsp; 3&gt;用java会产生系统难以支付的开销,如需要大量网络链接的场合;<br />&nbsp;&nbsp;&nbsp; 4&gt;存在大量可重用的c/c++代码,通过JNI可以减少开发工作量,避免重复开发.<br />另外,在利用JNI技术的时候要注意以下几点:<br />&nbsp;&nbsp;&nbsp; 1&gt;由于Java安全机制的限制,不要试图通过Jar文件的方式发布包含本地化方法的Applet到客户端;<br />&nbsp;&nbsp;&nbsp; 2&gt;注意内存管理问题,虽然在本地方法返回Java后将自动释放局部引用,但过多的局部引用将使虚拟机在执行本地方法时耗尽内存;<br />&nbsp;&nbsp;&nbsp; 3&gt;JNI技术不仅可以让java程序调用c/c++代码,也可以让c/c++代码调用java代码.  </p><p>注:有一个名叫Jawin开源项目实现了直接读取第三方dll文件,不用自己辛苦去手写一个起传值转换作用的dll文件,有兴趣的可以研究一下.但是我用的时候不太顺手,有很多规则限制,像自己写程序时可以随意定义返回值,随意转换类型,用这个包的话这些都是不可能的了,所以我的项目还没开始就把它抛弃了.</p><img src ="http://www.blogjava.net/wuhen86/aggbug/355212.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-07-28 12:37 <a href="http://www.blogjava.net/wuhen86/articles/355212.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>J2EE 13种技术规范</title><link>http://www.blogjava.net/wuhen86/articles/355211.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Thu, 28 Jul 2011 04:34:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/355211.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/355211.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/355211.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/355211.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/355211.html</trackback:ping><description><![CDATA[<p><strong><u>J2EE</u></strong>平台由一整套服务（Services）、应用程序接口（APIs）和协议构成，它对开发基于Web的多层应用提供了功能支持，下面对<strong><u>J2EE</u></strong>中的13种技术规范进行简单的描述(限于篇幅，这里只能进行简单的描述):<br />1.JDBC(Java Database Connectivity):<br />JDBC API为访问不同的数据库提供了一种统一的途径，象ODBC一样，JDBC对开发者屏蔽了一些细节问题，另外，JDCB对数据库的访问也具有平台无关性。<br />2.JNDI(Java Name and Directory Interface):<br />JNDI API被用于执行名字和目录服务。它提供了一致的模型来存取和操作企业级的资源如DNS和LDAP，本地文件系统，或应用服务器中的对象。<br />3.EJB(Enterprise JavaBean):<br /><strong><u>J2EE</u></strong>技术之所以赢得某体广泛重视的原因之一就是EJB。它们提供了一个框架来开发和实施分布式商务逻辑，由此很显著地简化了具有可伸缩性和高度复杂的企业级应用的开发。EJB规范定义了EJB组件在何时如何与它们的容器进行交互作用。容器负责提供公用的服务，例如目录服务、事务管理、安全性、资源缓冲池以及容错性。但这里值得注意的是，EJB并不是实现<strong><u>J2EE</u></strong>的唯一途径。正是由于<strong><u>J2EE</u></strong>的开放性，使得有的厂商能够以一种和EJB平行的方式来达到同样的目的。<br />4.RMI(Remote Method Invoke):<br />正如其名字所表示的那样，RMI协议调用远程对象上方法。它使用了序列化方式在客户端和服务器端传递数据。RMI是一种被EJB使用的更底层的协议。<br />5.Java IDL/CORBA:<br />在Java IDL的支持下，开发人员可以将Java和CORBA集成在一起。 他们可以创建Java对象并使之可在CORBA ORB中展开, 或者他们还可以创建Java类并作为和其它ORB一起展开的CORBA对象的客户。后一种方法提供了另外一种途径，通过它Java可以被用于将你的新的应用和旧的系统相集成。<br />6.JSP(Java Server Pages):<br />JSP页面由HTML代码和嵌入其中的Java代码所组成。服务器在页面被客户端所请求以后对这些Java代码进行处理，然后将生成的HTML页面返回给客户端的浏览器。<br />7.Java Servlet:<br />Servlet是一种小型的Java程序，它扩展了Web服务器的功能。作为一种服务器端的应用，当被请求时开始执行，这和CGI Perl脚本很相似。Servlet提供的功能大多与JSP类似，不过实现的方式不同。JSP通常是大多数HTML代码中嵌入少量的Java代码，而servlets全部由Java写成并且生成HTML。<br />8.XML(Extensible Markup Language):<br />XML是一种可以用来定义其它标记语言的语言。它被用来在不同的商务过程中共享数据。XML的发展和Java是相互独立的，但是，它和Java具有的相同目标正是平台独立性。通过将Java和XML的组合，您可以得到一个完美的具有平台独立性的解决方案。<br />9.JMS(Java Message Service):<br />MS是用于和面向消息的中间件相互通信的应用程序接口(API)。它既支持点对点的域，有支持发布/订阅(publish/subscribe)类型的域，并且提供对下列类型的支持：经认可的消息传递,事务型消息的传递，一致性消息和具有持久性的订阅者支持。JMS还提供了另一种方式来对您的应用与旧的后台系统相集成。<br />10.JTA(Java Transaction Architecture):<br />JTA定义了一种标准的API，应用系统由此可以访问各种事务监控。<br />11.JTS(Java Transaction Service):<br />JTS是CORBA OTS事务监控的基本的实现。JTS规定了事务管理器的实现方式。该事务管理器是在高层支持Java Transaction API (JTA)规范，并且在较底层实现OMG OTS specification的Java映像。JTS事务管理器为应用服务器、资源管理器、独立的应用以及通信资源管理器提供了事务服务。<br />12.JavaMail:<br />JavaMail是用于存取邮件服务器的API，它提供了一套邮件服务器的抽象类。不仅支持SMTP服务器，也支持IMAP服务器。<br />13.JAF(JavaBeans Activation Framework):<br />JavaMail利用JAF来处理MIME编码的邮件附件。MIME的字节流可以被转换成Java对象，或者转换自Java对象。大多数应用都可以不需要直接使用JAF。  </p><p>&nbsp; </p><p>转自:<a href="http://hi.baidu.com/dinguangx/blog/item/c6f5003ddcd688c19e3d6279.html">http://hi.baidu.com/dinguangx/blog/item/c6f5003ddcd688c19e3d6279.html</a></p><img src ="http://www.blogjava.net/wuhen86/aggbug/355211.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-07-28 12:34 <a href="http://www.blogjava.net/wuhen86/articles/355211.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>pl/sql中添加 shortcuts插件</title><link>http://www.blogjava.net/wuhen86/articles/355188.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Thu, 28 Jul 2011 01:05:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/355188.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/355188.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/355188.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/355188.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/355188.html</trackback:ping><description><![CDATA[<p>在pl/sql中添加快捷键的支持只需要把一个文本类型的文件plugin.txt放入到pl/sql安装目录下的plugins文件夹中。</p> <p>其中plugin.txt 文件中的内容为（自定义的内容，可以根据自己的习惯设置）：</p> <p>s = select * from <br />sc* = select count(*) from <br />w = where <br />ss = select /*+parallel(a,6)*/ * from </p> <p>打开pl/sql developer进入[首选项]-&gt;[用户界面]-&gt;[编辑器]-&gt;[autoreplace]，选中enabled复选框，再查找 plugin.txt所在的路径，点击[应用]即完成插件的安装。</p> <p>重启pl/sql developer，打开sql编辑窗口，输入s，再按空格，就可以出现select * from，这样就可以不必每次都输入这段经常使用而又经常打错的语句了。</p><img src ="http://www.blogjava.net/wuhen86/aggbug/355188.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-07-28 09:05 <a href="http://www.blogjava.net/wuhen86/articles/355188.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>myeclipse工程改为Eclipse</title><link>http://www.blogjava.net/wuhen86/articles/351347.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Mon, 30 May 2011 08:33:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/351347.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/351347.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/351347.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/351347.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/351347.html</trackback:ping><description><![CDATA[修改eclipse工程下的.project文件： 
在<natures></natures>中加入 
              <nature>org.eclipse.wst.common.project.facet.core.nature</nature><nature>org.eclipse.wst.common.modulecore.ModuleCoreNature</nature><nature>org.eclipse.jem.workbench.JavaEMFNature</nature> 
在<buildspec></buildspec>中加入 
              <buildcommand><name>org.eclipse.wst.common.project.facet.core.builder</name><arguments></arguments></buildcommand><buildcommand><name>org.eclipse.wst.validation.validationbuilder</name><arguments></arguments></buildcommand> 
做完以上步驟後，刷新项目；點擊右鍵-&gt;项目-&gt;右键 -&gt;Properties-&gt;Project Facets-&gt;Modify Project在弹出的面板中，选择Java和Dynamic Web Module 下一步是配置Context Root 和Content Directory 以及源码路径，配置完成。<img src ="http://www.blogjava.net/wuhen86/aggbug/351347.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-05-30 16:33 <a href="http://www.blogjava.net/wuhen86/articles/351347.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>如何不重新启动 Emacs 就让 .emacs 的配置起作用</title><link>http://www.blogjava.net/wuhen86/articles/350470.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Wed, 18 May 2011 05:53:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/350470.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/350470.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/350470.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/350470.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/350470.html</trackback:ping><description><![CDATA[<p><span style="widows: 2; text-transform: none; text-indent: 0px; border-collapse: separate; font: medium Simsun; white-space: normal; orphans: 2; letter-spacing: normal; color: #000000; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px" class="Apple-style-span">我刚刚使用 Emacs 的时候，总是</span></p>
<pre style="border-bottom: #777777 1px solid; border-left: #777777 1px solid; padding-bottom: 0.5em; background-color: #e6e6e6; padding-left: 0.5em; padding-right: 0.5em; font-family: Fixedsys; white-space: pre; color: black; margin-left: 1em; font-size: 12pt; border-top: #777777 1px solid; margin-right: 2em; border-right: #777777 1px solid; padding-top: 0.5em" xml:space="preserve" class="example">vi ~/.emacs
</pre>
<p>然后重新启动 emacs ，效率很低 ，暗自嘟囔， emacs 怎么没有这种功能，不重起，就自动更新 .emacs 的设置 呢？</p>
<p>后来我发现，这个功能完全没有必要，我的做法是:</p>
<ul>
<li>用 emacs 打开 .emacs 文件，C-x C-e 光标前面的运行一条语句。立即生效。</li>
<li>选择一个 region , M-x eval-region</li>
<li>M-x load-file ~/.emacs</li>
<li>M-x eval-buffer</li>
</ul>
<p>都是立即生效，可以马上试验一条语句的效果。 例如，在任何一个文件中，写</p>
<pre style="border-bottom: #999999 1px solid; border-left: #999999 1px solid; padding-bottom: 0.4em; line-height: 10px; background-color: #fafaff; margin: 0.5em 2em 1em 1em; padding-left: 0.4em; padding-right: 0.4em; font-family: sans-serif; white-space: pre; color: black; font-size: 12px; border-top: #999999 1px solid; border-right: #999999 1px solid; padding-top: 0px" xml:space="preserve" class="src">(setq frame-title-format <span style="color: #bc8f8f">"emacs@%b"</span>)
</pre>
<p>把光标停在在这条语句后面， C-x C-e ，马上看到 emacs 的 标题栏上发生变化。</p>
<p>我用这种方法调试我的每一个小的配置文件，按上篇文章说的方法， 把他放在 ~/Emacs/myconfig/my-site-start.d 中。</p>
<p>转自:<a href="http://ann77.emacser.com/Emacs/EmacsDotEmacsWithoutRestart.html">http://ann77.emacser.com/Emacs/EmacsDotEmacsWithoutRestart.html</a></p>
<p class="zoundry_bw_tags">
  <!-- Tag links generated by Zoundry Blog Writer. Do not manually edit. http://www.zoundry.com -->
  <span class="ztags"><span class="ztagspace">Technorati</span> : <a href="http://technorati.com/tag/Emacs" class="ztag" rel="tag">Emacs</a>, <a href="http://technorati.com/tag/%E9%85%8D%E7%BD%AE" class="ztag" rel="tag">配置</a></span> 
</p><img src ="http://www.blogjava.net/wuhen86/aggbug/350470.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2011-05-18 13:53 <a href="http://www.blogjava.net/wuhen86/articles/350470.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>Emacs快捷键</title><link>http://www.blogjava.net/wuhen86/articles/329476.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Fri, 20 Aug 2010 08:01:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/329476.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/329476.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/329476.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/329476.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/329476.html</trackback:ping><description><![CDATA[<h4>基本命令</h4>
<p>C-x C-c : 退出Emacs  </p>
<p>C-x C-f : 打开一个文件，如果文件不存在，则创建一个文件  </p>
<p>C-g : 取消未完成的命令  </p>
<h4>编辑</h4>
<p><em>C-z</em> (redefined): Undo；原来C-z是挂起Emacs（然后用fg命令调出）；C-x u 是默认的命令； 移动一下光标，再C-z就可以redo  </p>
<p>M-d : 删除光标后的词语  </p>
<h4>移动光标</h4>
<p>C-v : 向前翻页  </p>
<p>M-v : 向后翻页  </p>
<p>M-r : 将光标移动到屏幕中间那行  </p>
<p>C-a : 移到行首  </p>
<p>M-a : 移到句首，从行首到句首之间可能有空格  </p>
<p>C-e : 移到行尾  </p>
<p>M-e : 移到句尾  </p>
<p>M-{ : 向上移动一段  </p>
<p>M-} : 向下移动一段  </p>
<p>C-right : 向前移动一个单词  </p>
<p>C-left : 向后移动一个单词  </p>
<p>C-up : 向前移动一段  </p>
<p>C-down : 向后移动一段  </p>
<p>M-&lt; : 移到整个文本开头  </p>
<p>M-&gt; : 移到整个文本末尾  </p>
<p>C-u 数字 命令 : 执行多次(数字表示次数)该命令；&#8220;M-数字 命令&#8221; 也可以  </p>
<p>M-x goto-line : 移动到某一行  </p>
<p>C-l : 重绘屏幕，效果就是当前编辑行移动窗口中央  </p>
<h4>Buffer 相关</h4>
<p>C-x k : 关闭当前buffer  </p>
<p>C-x b : 切换到前一个编辑的buffer  </p>
<p>C-x C-b : 列出当前所有buffer  </p>
<p>C-x C-s : 保存当前buffer  </p>
<p>C-x s : 保存所有未保存的buffer，会提示你是否需要保存  </p>
<p>C-x C-w : 文件另存为  </p>
<h4>拷贝与粘贴</h4>
<p><em>M-space</em> (redefined): 设置mark; C-@ 是默认命令  </p>
<p><em>C-w</em> (redefined) : 剪切一块区域；如果没有设置mark，则是剪切一行  </p>
<p><em>M-w</em> (redefined) : 拷贝一块区域；如果没有设置mark, 则是拷贝一行  </p>
<p>C-k : 从当前位置剪切到行尾  </p>
<p>C-y : 粘贴  </p>
<p>M-y : 用C-y拉回最近被除去的文本后，换成 M-y可以拉回以前被除去的文本。键入多次的M-y可以拉回更早以前被除去的文本。  </p>
<p>C-x r k : 执行矩形区域的剪切  </p>
<p>C-x r y : 执行矩形区域的粘贴  </p>
<h4>窗口操作</h4>
<p>C-x 0 : 关闭当前窗口  </p>
<p>C-x 1 : 将当前窗口最大化  </p>
<p>C-x 2 : 垂直分割窗口  </p>
<p>C-x 3 : 水平分割窗口  </p>
<p><em>M-o</em> (redefined) : 在窗口之间切换; C-x o 是默认命令  </p>
<p>C-x 5 1/2/3/0 : 对frame类似的操作  </p>
<p>C-x &lt; : 窗口内容右卷  </p>
<p>C-x &gt; : 窗口内容左卷（这两个命令在垂直分割窗口后比较有用）  </p>
<p>(C-u) C-x ^ : 加高当前窗口，如果有C-u，则每次加高4行  </p>
<p>(C-u) C-x } : 加宽当前窗口  </p>
<p>(C-u) C-x { : 压窄当前窗口  </p>
<p>ESC C-v : 在其它窗口进行卷屏操作  </p>
<h4>搜索和替换</h4>
<p>C-s : 向前搜索（增量式搜索）；连续C-s，跳到下一个搜索到的目标  </p>
<p>C-s RET : 普通搜索  </p>
<p>C-r : 向前搜索  </p>
<p>C-s RET C-w : 按单词查询  </p>
<p>M-% : 查询替换，也就是替换前会询问一下  </p>
<p>M-x replace-string : 普通替换  </p>
<h4>Tags</h4>
<p>M-! etags <em>.c </em>.h : 创建TAGS文件  </p>
<p>M-. : 跳到tag所在位置  </p>
<p>M-x list-tags : 列出tags  </p>
<h4>Bookmark</h4>
<p>C-x r m : 设置书签bookmark  </p>
<p>C-x r b : 跳到bookmark处  </p>
<h4>帮助</h4>
<p>C-h ? : 查看帮助信息  </p>
<p>C-h f : 查看一个函数  </p>
<p>C-h v : 查看一个变量  </p>
<p>C-h k : 查看一个键绑定 (C－h c 也是查看键绑定，但是信息较简略)  </p>
<p>C-h C-f : 查看一个函数的Info，非常有用  </p>
<p>C-h i : 看Info  </p>
<h4>其它</h4>
<p>C-M-\ : 对选中区域，按照某种格式(比如C程序)进行格式化  </p>
<p>C-x h : 全部选中  </p>
<p>M-! : 执行外部shell命令  </p>
<p>M-x shell : 模拟shell的buffer  </p>
<p>M-x term : 模拟terminal, C-c k 关闭terminal  </p>
<p>C-x C-q : 修改buffer的只读属性  </p>
<p>翻页 <br />
C-v 下一页 <br />
M-v 上一页 <br />
选择 <br />
M-h&nbsp;&nbsp;&nbsp;&nbsp; 选择段落 <br />
C-x h&nbsp;&nbsp; 全部选择 <br />
普通区块 <br />
C-SPC&nbsp;&nbsp; M-x set-mark-command 单个位置set mark <br />
C-@&nbsp;&nbsp;&nbsp;&nbsp; 同上 <br />
M-@&nbsp;&nbsp;&nbsp;&nbsp; 对word进行set Mark <br />
M-w&nbsp;&nbsp;&nbsp;&nbsp; 先set Mark，移到光标，M-w就可以复制 <br />
C-w&nbsp;&nbsp;&nbsp;&nbsp; 剪切 <br />
矩形区块 <br />
用这些快捷键要先关闭cua-mode <br />
C-x r t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 用串填充矩形区域 <br />
C-x r o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插入空白的矩形区域 <br />
C-x r y&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插入之前删除的矩形区域, 粘贴时，矩形左上角对齐光标 <br />
C-x r k&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除矩形区域 <br />
C-x r c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将当前矩形区域清空 <br />
寄存器 <br />
---------------------------------------------------------------------- <br />
光标位置和窗口状态 <br />
C-x r SPC &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 存贮光标位置 <br />
C-x r w &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 保存当前窗口状态 <br />
C-x r f &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 保存所有窗口状态 <br />
C-x r j &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 光标跳转 <br />
文本和数字 <br />
C-x r s &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将连续区块拷贝到寄存器中 <br />
C-x r r &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将矩形区块拷贝到寄存器中 <br />
C-u &lt;数字&gt; C-x r n &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 将数字拷贝到寄存器中 <br />
C-x r i &lt;寄存器名&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 在缓冲区中插入寄存器内容 <br />
M-x view-register&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看寄存器内容 <br />
M-x list-registers&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看寄存器列表 <br />
宏模式 <br />
C-x (&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 开始一个宏的定义 <br />
C-x )&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 结束一个宏的定义 <br />
C-x e&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 执行宏 <br />
M-x name-last-kbd-macro&nbsp; 给最后一个宏命名 <br />
M-x insert-kbd-macro&nbsp;&nbsp;&nbsp;&nbsp; 在当前文件中插入一个已定义并命名过的宏 <br />
书签 <br />
C-x r m &lt;name&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设置书签 <br />
C-x r b &lt;name&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 跳转到书签 <br />
C-x r l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 书签列表 <br />
M-x bookmark-delete&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除书签 <br />
M-x bookmark-load&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 读取存储书签文件 <br />
M-x bookmark-save&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 保存到文件 <br />
目录模式 <br />
---------------------------------------------------------------------- <br />
C-x d&nbsp;&nbsp;&nbsp;&nbsp; M-x dired&nbsp;&nbsp;&nbsp;&nbsp; 启动目录模式 <br />
C-x C-d&nbsp;&nbsp; 简单目录 </p>
<p>&nbsp; </p>
<p>程序 <br />
C-x C-z 挂起程序 <br />
C-c C-x 退出程序 <br />
C-c k&nbsp;&nbsp; 关闭buffer <br />
C-l&nbsp;&nbsp;&nbsp;&nbsp; 重画屏幕 <br />
C-g&nbsp;&nbsp;&nbsp;&nbsp; 结束命令，或者假死中恢复，也可以按3次ESC <br />
文件 <br />
C-x C-s 保存 <br />
C-x C-w 另存为 <br />
C-x C-f 打开文件 <br />
C-x C-r 只读方式打开 <br />
C-x C-v 读入另外一个文件代替当前buffer的文件 <br />
C-x s&nbsp;&nbsp; 保存所有 <br />
C-x i&nbsp;&nbsp; 将文件的内容插入 <br />
M-x revert-buffer&nbsp;&nbsp;&nbsp; 恢复到原始状态 <br />
跳转 <br />
前/后&nbsp;&nbsp;&nbsp;&nbsp; 单位 <br />
C-f/b&nbsp;&nbsp;&nbsp; 字 <br />
M-f/b&nbsp;&nbsp;&nbsp; 词 <br />
C-a/e&nbsp;&nbsp;&nbsp; 行内 <br />
M-a/e&nbsp;&nbsp;&nbsp; 句 <br />
M-&lt;/&gt;&nbsp;&nbsp;&nbsp; 文档 <br />
C-p/n&nbsp;&nbsp;&nbsp; 行间 <br />
M-{/}&nbsp;&nbsp;&nbsp; 段落 <br />
C-x ]/[&nbsp; 页 <br />
C-x C-x&nbsp; 文件内，mark之间 <br />
M-g g&nbsp; 跳到指定行 <br />
M-x goto-char 跳到指定字符 <br />
编辑 <br />
M-u&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后面单词变为大写 <br />
M-l&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后面单词变为小写 <br />
M-c&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 后面单词的首字母变大写 <br />
M-/&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 补全 <br />
C-j&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 从当前位置分成两行,相当于RET + tab <br />
M-(&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插入() <br />
C-q tab&nbsp;&nbsp; 插入tab <br />
C-q C-m&nbsp;&nbsp; 插入^M <br />
M-;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 插入注释 <br />
C-o&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 回车 <br />
删除 <br />
M-d&nbsp;&nbsp; 后一词 <br />
C-d&nbsp;&nbsp; 后一字 <br />
M-del 前一词 <br />
M-k&nbsp;&nbsp; 到句尾 <br />
M-"&nbsp;&nbsp; 前面的所有空白 <br />
M-z&nbsp;&nbsp; 删到指定字母处 <br />
C-k&nbsp;&nbsp; 删除到行尾 <br />
文本换位 <br />
C-t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 字符 <br />
M-t&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 单词 <br />
C-x C-t&nbsp;&nbsp;&nbsp; 行 <br />
M-x transpose-* 其他命令 <br />
撤销 <br />
C-/ <br />
C-x u <br />
C-_ <br />
C-z <br />
重做 <br />
C-g M-x undo <br />
C-g C-/ <br />
C-g C-z <br />
C-g C-_ <br />
粘贴 <br />
C-y <br />
C-v <br />
tab/空格转换 <br />
M-x tabify <br />
M-x untabify <br />
让选择的区块自动对齐 <br />
M-x indent-region <br />
其他命令 <br />
C-u &lt;数字&gt; &lt;命令&gt; 重复命令n次 <br />
M-&lt;数字&gt;&nbsp;&nbsp; &lt;命令&gt; 同上 <br />
M-!&nbsp;&nbsp;&nbsp;&nbsp; 运行shell命令 <br />
C-u M-! 执行一条外部命令，并输出到光标位置 <br />
M-x cd&nbsp; 改变工作目录 <br />
M-x pwd 当前工作目录 <br />
C-" 启动输入法 <br />
M-` 菜单 <br />
F10 菜单 <br />
M-x eval-buffer 在.emacs的buffer中运行，重新加载emacs配置 <br />
查找替换 <br />
---------------------------------------------------------------------- <br />
C-r 向上查找 <br />
C-s 向下查找 <br />
C-s C-w 向下查找，光标位置的单词作为查找字符串 <br />
C-s C-y 向下查找，光标位置到行尾作为查找字符串 <br />
C-s RET &lt;查找字符串&gt; RET&nbsp;&nbsp; 非递增查找 <br />
C-s RET C-w&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 不受换行、空格、标点影响 <br />
C-M-s&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 正则式向下查找 <br />
用向上查找命令就将上面命令的s替换为r <br />
M-%&nbsp;&nbsp; 替换 <br />
C-M-% 正则式替换 <br />
y 替换当前的字符串并移动到下一个字符串 <br />
n 不替换当前字符串，直接移动到下一个字符串 <br />
! 进行全局替换，并要求不再显示 <br />
. 替换当前字符串，然后退出查找替换操作 <br />
q 退出查找替换操作，光标定位到操作开始时的位置 <br />
其他命令 <br />
M-x replace-* <br />
M-x search-* <br />
窗口 <br />
C-x 0 关掉当前窗口 <br />
C-x 1 关掉其他窗口 <br />
C-x o 切换窗口 <br />
C-x 2 水平两分窗口 <br />
C-x 3 垂直两分窗口 <br />
C-x 5 2 新frame <br />
buffer <br />
C-x C-b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 查看 <br />
C-x b&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 切换 <br />
C-x C-q&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 设为只读 <br />
C-x k&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 删除 <br />
C-x left/right 切换</p>
<img src ="http://www.blogjava.net/wuhen86/aggbug/329476.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2010-08-20 16:01 <a href="http://www.blogjava.net/wuhen86/articles/329476.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>JSF2.0初探</title><link>http://www.blogjava.net/wuhen86/articles/325634.html</link><dc:creator>无很</dc:creator><author>无很</author><pubDate>Fri, 09 Jul 2010 04:51:00 GMT</pubDate><guid>http://www.blogjava.net/wuhen86/articles/325634.html</guid><wfw:comment>http://www.blogjava.net/wuhen86/comments/325634.html</wfw:comment><comments>http://www.blogjava.net/wuhen86/articles/325634.html#Feedback</comments><slash:comments>2</slash:comments><wfw:commentRss>http://www.blogjava.net/wuhen86/comments/commentRss/325634.html</wfw:commentRss><trackback:ping>http://www.blogjava.net/wuhen86/services/trackbacks/325634.html</trackback:ping><description><![CDATA[<p>一直想研究Java JSF,上网找了下,遗憾的是国内JSF的资料少的可怜.于是上网找了参考点资料,去官方网站下载了JSF的开发包.废话少说,看配置.</p>
<p>一,配置JSF</p>
<p>把JSF2.0内的两个开发包jsf-api.jar,jsf-impl.jar拷贝到Eclipse项目的lib目录中(建立web项目略). 在web.xml中添加以下内容:</p>
<p>&lt;context-param&gt;
<br />
&lt;param-name&gt;javax.faces.STATE_SAVING_METHOD&lt;/param-name&gt;
<br />
&lt;param-value&gt;client&lt;/param-value&gt;
<br />
&lt;/context-param&gt;</p>
<p>&lt;context-param&gt;
<br />
&lt;param-name&gt;javax.faces.PROJECT_STAGE&lt;/param-name&gt;
<br />
&lt;param-value&gt;Development&lt;/param-value&gt;
<br />
&lt;/context-param&gt;</p>
<p>&lt;context-param&gt;
<br />
&lt;param-name&gt;com.sun.faces.resourceUpdateCheckPeriod&lt;/param-name&gt;
<br />
&lt;param-value&gt;-1&lt;/param-value&gt;
<br />
&lt;/context-param&gt;</p>
<p>&lt;servlet&gt;
<br />
&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
<br />
&lt;servlet-class&gt;javax.faces.webapp.FacesServlet&lt;/servlet-class&gt;
<br />
&lt;load-on-startup&gt;1&lt;/load-on-startup&gt;
<br />
&lt;/servlet&gt;
<br />
&lt;servlet-mapping&gt;
<br />
&lt;servlet-name&gt;Faces Servlet&lt;/servlet-name&gt;
<br />
&lt;url-pattern&gt;*.do&lt;/url-pattern&gt; &lt;!--此处名字可以随便起,可以是*.action,*.faces 等 我习惯用*.do--&gt;
<br />
&lt;/servlet-mapping&gt;</p>
<p>这样jsf框架已经添加进项目中了.接下来就要建立Bean了.如下所示:</p>
<p>package com.joy.jsf.beans;</p>
<p><a>//@ManagedBean(name="users</a>") jsf2.0可以不用配置文件来管理bean
<br />
public class User {</p>
<p>private String userName;
<br />
private String userPassword;
<br />
private String errorMessage;</p>
<p>public String getErrorMessage() {
<br />
return errorMessage;
<br />
}</p>
<p>public void setErrorMessage(String errorMessage) {
<br />
this.errorMessage = errorMessage;
<br />
}</p>
<p>public String getUserName() {
<br />
return userName;
<br />
}</p>
<p>public void setUserName(String userName) {
<br />
this.userName = userName;
<br />
}</p>
<p>public String getUserPassword() {
<br />
return userPassword;
<br />
}</p>
<p>public void setUserPassword(String userPassword) {
<br />
this.userPassword = userPassword;
<br />
}</p>
<p>public String Check() {
<br />
if (!this.userName.equals("JOY") || !this.userPassword.equals("123456")) {
<br />
this.errorMessage = "名称或密码错误";
<br />
return "failure";
<br />
} else {
<br />
return "success";
<br />
}
<br />
}
<br />
}</p>
<p>之后要定制导航规则,新建face-config.xml 如下所示:</p>
<p>&lt;faces-config&gt;
<br />
&lt;!-- &lt;application&gt;
<br />
&lt;variable-resolver&gt;
<br />
org.springframework.web.jsf.DelegatingVariableResolver
<br />
&lt;/variable-resolver&gt;
<br />
&lt;/application&gt; --&gt;
<br />
&lt;navigation-rule&gt;
<br />
&lt;from-view-id&gt;/index.jsp&lt;/from-view-id&gt;
<br />
&lt;navigation-case&gt;
<br />
&lt;from-outcome&gt;success&lt;/from-outcome&gt;
<br />
&lt;to-view-id&gt;/pages/welcome.jsp&lt;/to-view-id&gt;
<br />
&lt;/navigation-case&gt;
<br />
&lt;navigation-case&gt;
<br />
&lt;from-outcome&gt;failure&lt;/from-outcome&gt;
<br />
&lt;to-view-id&gt;/index.jsp&lt;/to-view-id&gt;
<br />
&lt;/navigation-case&gt;
<br />
&lt;/navigation-rule&gt;</p>
<p>&lt;!--&lt;managed-bean&gt; &lt;managed-bean-name&gt;users&lt;/managed-bean-name&gt; &lt;managed-bean-class&gt;
<br />
com.joy.jsf.beans.User &lt;/managed-bean-class&gt; &lt;managed-bean-scope&gt;request&lt;/managed-bean-scope&gt;
<br />
&lt;/managed-bean&gt; --&gt;
<br />
&lt;/faces-config&gt;</p>
<p>配置文件建立完了,添加view页面. index.jsp和welcome.jsp</p>
<p>index.jsp</p>
<p>&lt;%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%&gt;
<br />
&lt;%@ taglib prefix="f" uri="<a href="http://java.sun.com/jsf/core&quot;%">http://java.sun.com/jsf/core"%</a>&gt;
<br />
&lt;%@ taglib prefix="h" uri="<a href="http://java.sun.com/jsf/html&quot;%">http://java.sun.com/jsf/html"%</a>&gt;
<br />
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<a href="http://www.w3.org/TR/html4/loose.dtd">http://www.w3.org/TR/html4/loose.dtd</a>"&gt;
<br />
&lt;html&gt;
<br />
&lt;head&gt;
<br />
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
<br />
&lt;title&gt;首页&lt;/title&gt;
<br />
&lt;/head&gt;
<br />
&lt;body&gt;
<br />
&lt;f:view&gt;
<br />
&lt;h:form&gt;
<br />
姓名:&lt;h:inputText value="#{users.userName }" /&gt;&lt;br/&gt;
<br />
密码:&lt;h:inputText value="#{users.userPassword }"&gt;&lt;/h:inputText&gt;&lt;br/&gt;
<br />
&lt;h:commandButton value="submit" action="#{users.Check}"&gt;&lt;/h:commandButton&gt;
<br />
&lt;br/&gt;
<br />
&lt;h:outputText value="#{users.errorMessage}"/&gt;&lt;p&gt;
<br />
<br />
&lt;/h:form&gt;
<br />
&lt;/f:view&gt;
<br />
&lt;/body&gt;
<br />
&lt;/html&gt;</p>
<p>welcome.jsp</p>
<p>&lt;%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8"%&gt;
<br />
&lt;%@ taglib prefix="f" uri="<a href="http://java.sun.com/jsf/core&quot;%">http://java.sun.com/jsf/core"%</a>&gt;
<br />
&lt;%@ taglib prefix="h" uri="<a href="http://java.sun.com/jsf/html&quot;%">http://java.sun.com/jsf/html"%</a>&gt;
<br />
&lt;!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "<a href="http://www.w3.org/TR/html4/loose.dtd">http://www.w3.org/TR/html4/loose.dtd</a>"&gt;
<br />
&lt;html&gt;
<br />
&lt;head&gt;
<br />
&lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8"&gt;
<br />
&lt;title&gt;欢迎回来&lt;/title&gt;
<br />
&lt;/head&gt;
<br />
&lt;body&gt;
<br />
&lt;f:view&gt;
<br />
&lt;h:form&gt;
<br />
Hello &lt;h:outputText value="#{users.userName }"&gt;&lt;/h:outputText&gt; ,Welcome to here!
<br />
<br />
&lt;/h:form&gt;
<br />
&lt;/f:view&gt;
<br />
&lt;/body&gt;
<br />
&lt;/html&gt;</p>
<p>保存,部署,运行<a href="http://localhost:8080/JSF/index.do">http://localhost:8080/JSF/index.do</a></p>
<p>二,整合Spring</p>
<p>添加spring开发包,spring.jar,stadard.jar,commons-logging.jar,jstl.jar</p>
<p>web.xml 添加如下配置</p>
<p>&lt;context-param&gt;
<br />
&lt;param-name&gt;contextConfigLocation&lt;/param-name&gt;
<br />
&lt;param-value&gt;/WEB-INF/applicationContext.xml&lt;/param-value&gt;
<br />
&lt;/context-param&gt;</p>
<p>&lt;listener&gt;
<br />
&lt;description&gt;添加Srping支持&lt;/description&gt;
<br />
&lt;display-name&gt;Spring&lt;/display-name&gt;
<br />
&lt;listener-class&gt;org.springframework.web.context.ContextLoaderListener&lt;/listener-class&gt;
<br />
&lt;/listener&gt;</p>
<p>然后在face-config.xml中添加</p>
<p>&lt;application&gt;
<br />
&lt;variable-resolver&gt;
<br />
org.springframework.web.jsf.DelegatingVariableResolver
<br />
&lt;/variable-resolver&gt;
<br />
&lt;/application&gt;</p>
<p>从spring工厂中获取bean ,如果和jsf的托管bean一起使用,则托管bean的优先级要高于spring.</p>
<p>添加applicationContext.xml</p>
<p>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
<br />
&lt;beans xmlns="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a>"
<br />
xmlns:xsi="<a href="http://www.w3.org/2001/XMLSchema-instance">http://www.w3.org/2001/XMLSchema-instance</a>" xmlns:p="<a href="http://www.springframework.org/schema/p">http://www.springframework.org/schema/p</a>"
<br />
xmlns:aop="<a href="http://www.springframework.org/schema/aop">http://www.springframework.org/schema/aop</a>" xmlns:tx="<a href="http://www.springframework.org/schema/tx">http://www.springframework.org/schema/tx</a>"
<br />
xsi:schemaLocation="<a href="http://www.springframework.org/schema/beans">http://www.springframework.org/schema/beans</a> <a href="http://www.springframework.org/schema/beans/spring-beans-2.5.xsd">http://www.springframework.org/schema/beans/spring-beans-2.5.xsd</a>
<br />
<a href="http://www.springframework.org/schema/aop">http://www.springframework.org/schema/aop</a> <a href="http://www.springframework.org/schema/aop/spring-aop-2.5.xsd">http://www.springframework.org/schema/aop/spring-aop-2.5.xsd</a>
<br />
<a href="http://www.springframework.org/schema/tx">http://www.springframework.org/schema/tx</a> <a href="http://www.springframework.org/schema/tx/spring-tx-2.5.xsd">http://www.springframework.org/schema/tx/spring-tx-2.5.xsd</a>"&gt;</p>
<p>&lt;bean id="users" class="com.joy.jsf.beans.User"&gt;
<br />
<br />
&lt;/bean&gt;
<br />
&lt;/beans&gt;</p>
<p>重新部署,运行.</p>
<p>OK.</p>
<img src ="http://www.blogjava.net/wuhen86/aggbug/325634.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.blogjava.net/wuhen86/" target="_blank">无很</a> 2010-07-09 12:51 <a href="http://www.blogjava.net/wuhen86/articles/325634.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>