2010-02-17 11 views
5

Sto sviluppando alcune attività ant che tutte hanno bisogno di inizializzare gli stessi oggetti. Ho voluto inizializzare quelle di un oggetto in una superclasse comune che si estende da Task, nel metodo init(). Ma vedo da the lifecycle of an ant task che init() viene chiamato prima che gli elementi figlio e gli attributi delle attività siano impostati. Quindi tutti i dati di cui ho bisogno per inizializzare quegli oggetti non sono disponibili durante init(), se sto leggendo bene.Cosa si può fare nel metodo Task.init() della formica?

Quindi, perché init() viene chiamato a questo punto? Cosa sai che potresti usare in init()? Per cosa potrebbe essere usato?

(E c'è qualche altro metodo che posso contare su di essere chiamato prima di execute(), ma dopo il mio sono disponibili i dati?)

risposta

3

La migliore guida è guardare il codice sorgente delle attività che Ant porta con sé. Sembra esserci 3 casi d'uso principali per init():

  1. Pre-inizializzazione di oggetti delegati. Ad esempio, l'attività Sync delega la maggior parte del proprio lavoro a un oggetto sottostante, passando attraverso alcuni dei setXYZ() a questo delegato. L'istanziazione e la pre-configurazione di questo delegato devono avvenire prima che qualsiasi proprietà sia impostata sull'attività.
  2. Configurazione dei valori predefiniti per i valori delle proprietà, che si basano sulle impostazioni generali del progetto. Ad esempio, l'attività SSH inizializza il valore predefinito knownHosts esaminando una proprietà di sistema. Inoltre, l'oggetto Project è stato iniettato nell'attività dal chiamato init(), quindi l'attività può esaminarlo.
  3. Aggiunta di dipendenze di terze parti facoltative al classpath. Ad esempio, l'attività JUnit aggiunge varie dipendenze correlate a Junit. Questi possono essere caricati solo quando l'attività viene utilizzata, poiché sono opzionali.

Tutto quanto sopra potrebbe essere fatto all'interno del costruttore di compiti, ma l'uso di un metodo esplicito init() è in linea con il progetto di attività Ant.

Per quanto riguarda la seconda parte della domanda, no, non esiste un hook del ciclo di vita che viene chiamato tra le proprietà impostate e execute() chiamato. Devi farlo all'interno dello stesso execute().

2

Il metodo init() viene chiamato su ogni attività su analisi del creare un file e anche dopo che l'attività è stata associata al suo progetto proprietario. Quindi l'attività può eseguire lavori che coinvolgono un'istanza Project.

0

Perché non eseguire l'inizializzazione in un singleton e quindi ottenere le attività della formica per chiamare il singleton per ottenere i dati iniziali? Quindi paghi solo per l'inizializzazione una volta.

0

Per ottenere l'effetto di eseguire un'inizializzazione nella classe base prima che venga chiamato il metodo di esecuzione, è possibile implementare execute() nella classe base, creare questi oggetti e chiamare un metodo astratto dichiarato nella classe base. Per esempio:

public abstract class BaseClass extends Task { 
    public final void execute() { 
    Foo foo = createFoo(); 
    Bar bar = createBar(foo); 
    execute(foo,bar); 
    } 
    public abstract void execute(Foo foo, Bar bar); 
} 

public class BazTask extends BaseClass { 
    public void execute(Foo foo, Bar bar) { 
    System.out.println("foo is " + foo + " and bar is " + bar); 
    } 
} 

si potrebbe anche memorizzare gli oggetti creati come campi e dare il metodo un nome diverso (come executeTask) invece di sovraccarico sulla base dei parametri.

Problemi correlati