Grundsätzlich Sie extensibility oder Plugin-Design-Pattern implementieren möchten. Es gibt mehrere Möglichkeiten, dieses Szenario zu implementieren.
Jeweils die Komponente, die jemand anderem erlauben soll, das Modul neu zu laden, eine Schnittstelle definieren und eine eigene Implementierung als Standard implementieren.Zum Beispiel, hier versuche ich, eine HelloInterface zu schaffen, das jedes Land kann jederzeit implementieren und laden,
public interface HelloInterface {
public String sayHello(String input);
..
}
public class HelloImplDefault implements HelloInterface {
public String sayHello(String input) {
return "Hello World";
}
}
Jetzt Benutzer erlauben, ein Plugin (benutzerdefinierte Implementierung) Dateien zu einem vorkonfigurierten Pfad hinzuzufügen. Sie können entweder FileSystemWatcher oder einen Hintergrund-Thread verwenden, um diesen Pfad zu scannen und zu versuchen, die Datei zu kompilieren und zu laden.
Java-Datei zu kompilieren,
private void compile(List<File> files) throws IOException{
JavaCompiler compiler = ToolProvider.getSystemJavaCompiler();
DiagnosticCollector<JavaFileObject> diagnostics = new DiagnosticCollector<JavaFileObject>();
StandardJavaFileManager fileManager = compiler.getStandardFileManager(diagnostics, null, null);
Iterable<? extends JavaFileObject> compilationUnits = fileManager
.getJavaFileObjectsFromFiles(files);
JavaCompiler.CompilationTask task = compiler.getTask(null, fileManager, diagnostics, null,
null, compilationUnits);
boolean success = task.call();
fileManager.close();
}
Klassendatei zu laden,
private void load(List<File> files) throws MalformedURLException, InstantiationException, IllegalAccessException, ClassNotFoundException{
ClassLoader cl = Thread.currentThread().getContextClassLoader();
for(File f: files){
if(f.getName().endsWith(".class") && !loadedClass.contains(f.getName())){
URL url = f.toURL();
URL[] urls = new URL[]{url};
Object obj = cl.loadClass(f.getName().replace(".class", "")).newInstance();
if(obj instanceof HelloInterface){
HelloProviders.addProvider((HelloInterface)obj);
System.out.println("Loaded "+ ((HelloInterface)obj).getProviderName());
}else{
//Add more classes if you want
}
loadedClass.add(f.getName());
}
}
}
An dieser Stelle Sie benutzerdefinierte Implementierung und Systemklassenlader geladen lesen kann. Jetzt sind Sie bereit zu gehen. Dieser Ansatz hat Sicherheitsaspekte, die Sie aus dem Internet lernen müssen.
Ich habe einen Beispielcode implementiert und in GitHub, please take a look. Glückliche Kodierung!
http://www.beanshell.org/manual/embeddedmode.html –
Ich frage mich, niemand erwähnte OSGi. http://en.wikipedia.org/wiki/OSGi – Yser