2013-10-07 12 views
5

Ho solo circa un anno e mezzo di esperienza java, quindi scusate la mia mancanza di conoscenza. Ho provato a fare alcune ricerche su google, e ho alcune idee su questo, ci sono solo alcuni buchi che ho bisogno di compilare.Java Dynamic Factory

Sto provando a creare una "fabbrica dinamica" per un programma che sto facendo. La base di questo è che voglio che le persone siano in grado di inserire file di classe in una cartella e che vengano caricati nella mia fabbrica per crearne di nuovi in ​​seguito.

Questo è ciò che ho in questo momento:

import java.util.HashMap; 
import java.util.Map; 

public class KitManager { 

    private Map<String, Class<? extends Kit>> kitMap; 

    public KitManager() { 
     kitMap = new HashMap<String, Class<? extends Kit>>(); 
    } 

    public Kit makeKit(String kitname) { 
     try { 
      return kitMap.get(kitname).newInstance(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      return null; 
     } 
    } 
} 

Ora quello che sto cercando di capire è come ottenere tutte le classi all'interno di una cartella, assicurarsi che si estendono Kit, e poi inserirle nella mappa per avere istanze create successivamente. Questo è il punto in cui sono bloccato, non riesco a pensare a un buon modo per caricare le classi nella mappa senza che i nomi delle classi e le stringhe di ricerca vengano identificati da qualche parte in una configurazione. L'idea che avevo era di avere un codice statico all'interno di ogni classe che si inserisse in HashMap, ma non sono esattamente sicuro di come funzionerebbe. Tutto quello che chiedo veramente è un'idea su come realizzare il mio obiettivo. (Avere una cartella in cui gli utenti possono inserire classi in (che estendono Kit), e poi caricare dinamicamente queste classi nella mia kitMap quando viene caricato il mio programma)

risposta

2

Difficile dare una buona risposta quando i requisiti sono un po 'vaghi.

Da quello che dici, si può solo creare un ClassLoader che punta alla directory in cui gli utenti mettono le loro classi:

ClassLoader kitClassLoader = new URLClassLoader("file://<path>", KitManager.class.getClassLoader()); 

Per trovare effettivamente le classi, utilizzare un metodo semplice elenco di directory, ad esempio java.io.File.listFiles() (utilizzando un'istanza File che punta al percorso corretto, ovviamente):

File[] candidates = new File("<path>").listFiles(); 

è quindi possibile utilizzare il kitClassLoader per caricare in realtà una classe trovato:

kitClassLoader.loadClass(className); 

Classe i nomi che puoi derivare semplicemente dividendo l'estensione ".class" dai file trovati con listFiles(). Dopo aver caricato la classe, è possibile verificare che abbia effettivamente un costruttore predefinito e anche se implementa realmente Kit (in caso contrario, rifiutarlo o visualizzare un messaggio di errore).

Questo è fondamentalmente l'approccio, ma ha problemi di estrema sicurezza (non avete idea di quello che le classi in realtà saranno fare quando li si carica), e può anche introdurre problemi con le dipendenze (le classi si carica potrebbe richiedere ulteriori biblioteche?).

+0

Qual è esattamente lo scopo del caricatore di classe? Modifica: Quindi apparentemente i commenti non piace il codice all'interno di essi. Non sarei in grado di fare qualcosa come file.getClass(). AsSubclass (Kit.class) e aggiungerlo all'hashmap (assumendo che tutto sia configurato correttamente, il file estende il kit, ecc. Ecc.) – Phiction

+0

@ user2792581 Il * solo * modo per ottenere una classe nella VM è tramite un ClassLoader. Il problema è che File.getClass() semplicemente non esiste. ClassLoader è il bridge dai file di classe a una classe effettiva nella VM. – Durandal

+0

Suppongo che kitClassLoader.classForName (className); si riferisce a kitClassLoader.loadClass ()? – Phiction