ttp://www.amazon.{tld}/dp/{isbn}/)和一个包含有 tld=com,isbn=1411609255的Map,产生出URL http://www.amazon.com/dp/1411609255/( 这么做的一个原因是,如果Amazon URL模式发生了变化,我们能够改变该模板,尽管好的 URI是不会改变的)。
为了提供一个在不同实现之间切换的简单方法,我们将提供一个接口和一个工厂。这 会让我们看到在提供功能的同时实现是怎样对client隐藏的。代码(对应几个源文件)如 下:
package com.infoq.templater.api;
import java.util.*;
public interface ITemplater {
public String template(String uri, Map data);
}
// ---
package com.infoq.templater.api;
import com.infoq.templater.internal.*;
public class TemplaterFactory {
public static ITemplater getTemplater() {
return new Templater();
}
}
// ---
package com.infoq.templater.internal;
import com.infoq.templater.api.*;
import java.util.*;
public class Templater implements ITemplater {
public String template(String uri, Map data) {
String[] elements = uri.split("\\{|\\}");
StringBuffer buf = new StringBuffer();
for(int i=0;i
该实现隐藏在com.infoq.templater.internal包中,而public API则位于 com.infoq.templater.api包中。这就给了我们巨大的灵活性,如果需要,以后可以修改 实现以提供更加有效的手段。(internal包名是约定俗成,你可以起其他名字)。
为了让其他bundle能够访问该public API,我们需要将其export(输出)。我们的 manifest如下:
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.infoq.templater
Bundle-Version: 1.0.0
Export-Package: com.infoq.templater.api
创建一个client bundle
我们现在可以创建一个使用templater的client。利用上面的例子创建一个activator ,其start()方法如下:
package com.infoq.amazon;
import org.osgi.framework.*;
import com.infoq.templater.api.*;
import java.util.*;
public class Client implements BundleActivator {
public void start(BundleContext context) {
Map data = new HashMap();
data.put("tld", "co.uk"); // or "com" or "de" or ...
data.put("isbn", "1411609255"); // or "1586033115" or ...
System.out.println( "Starting\n" +
TemplaterFactory.getTemplater().template(
"http://www.amazon.{tld}/dp/{isbn}/", data));
}
public void stop(BundleContext context) {
}
}
模块化Java:静态模块化(4)
时间:2011-03-29 infoq Alex Blewitt 译:宋玮
我们需要在manifest中显式输入templater API,否则我们的bundle无法编译。用 Import-Package或Require-Bundle都可指定依赖。前者可以让我们单独输入包;后者则将 隐式输入该bundle中所有输出包。(多个包及bundles可以用逗号分开)。
Bundle-ManifestVersion: 2
Bundle-SymbolicName: com.infoq.amazon
Bundle-Version: 1.0.0
Bundle-Activator: com.infoq.amazon.Client
Import-Package: org.osgi.framework
Require-Bundle: com.infoq.templater
注意在前面的例子中,我们已经使用了Import-Package来输入org.osgi.framework。 在这个例子中,我们将演示 Require-Bundle的用法,其使用了Bundle-SymbolicName。当 然,用Import-Package: |