如何构建可扩展的Java应用程序?在应用程序不需要重新启动的情况下就能扩展或修改原有程序的功能?
Java API 中的ServiceLoader提供了解决方案!
参考示例:
1.构造一个接口
package com.test.spi;
public interface IHello {
public void sayHello();
}
2.实现接口的三个实例
实例1:
package com.test;
import com.test.spi.IHello;
public class Hello1 implements IHello{
public void sayHello(){
System.out.println("I am Hello#1");
}
}
实例2:
package com.test;
import com.test.spi.IHello;
public class Hello1 implements IHello{
public void sayHello(){
System.out.println("I am Hello#2");
}
}
实例3:
package com.test;
import com.test.spi.IHello;
public class Hello1 implements IHello{
public void sayHello(){
System.out.println("I am Hello#3");
}
}
如何实现程序的扩展呢?下面就是见证奇迹的时刻!
第一步:注意程序的包结构,按照包结构将这个工程打包为jar文件,不妨命名为test.jar(可以下载eclipse的打包工具插件fat jar)
第二步:用WinRAR压缩工具打开test.jar,在里面添加文件 META-INF/services/com.test.spi.IHello ,文件内容为:
com.test.Hello1
com.test.Hello2
(注意还行符)
第三步:构建测试工程,如HelloWorld,主类如下:
package extended;
import java.util.ServiceLoader;
import com.test.spi.IHello;
public class Main {
public static void main(String[] args) {
System.out.println("Hello!");
int loop = 0;
while(true){
System.out.println("Time:#"+(++loop));
ServiceLoader<IHello> loder=ServiceLoader.load(IHello.class);
for (IHello hello : loder) {
System.out.println(hello.getClass());
hello.SayHello("words");
}
try {
Thread.sleep(1000*5);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}
}
注意:将test.jar作为HelloWorld工程的外部依赖包,此程序即可通过ServiceLoader访问接口IHello 的两个实例Hello1和Hello2。运行此程序,即可循环输出"I am Hello#1",
"I am Hello#2 ".
第四步:构造extendtest.jar包!
构造过程同test.jar一样,也是首先压缩为jar包;然后再在包里面添加文件 META-INF/services/com.test.spi.IHello,文件内容为:
com.test.Hello1
com.test.Hello3
(注意还行符,test.jar中添加的文件内容为 com.tes.Hello1 和 com.test.Hello2)
第五步:修改第三步中运行着的工程的外部依赖包
右键工程-->BuildPath-->MigrateJAR File ,然后选择extendtest.jar的位置,并勾选下面的"Replace JAR File contents..."选项。
此时即可看到程序输出发生了改变! 程序循环输出
"I am Hello#1",
"I am Hello#3 ".
大功告成!PS:ServiceLoader只在jdk1.6及以上版本中使用
http://hi.baidu.com/cjry_8854/item/7015cb947c7acdbccc80e5e3