2012-08-02 13 views
5

Secondo Spring's documentation il modo di usare il TaskExecutor è la seguente:Come si autoregistra un thread creato da Spring TaskExecutor?

import org.springframework.core.task.TaskExecutor; 

public class TaskExecutorExample { 

    private class MessagePrinterTask implements Runnable { 

    private String message; 

    public MessagePrinterTask(String message) { 
     this.message = message; 
    } 

    public void run() { 
     System.out.println(message); 
    } 

    } 

    private TaskExecutor taskExecutor; 

    public TaskExecutorExample(TaskExecutor taskExecutor) { 
    this.taskExecutor = taskExecutor; 
    } 

    public void printMessages() { 
    for(int i = 0; i < 25; i++) { 
     taskExecutor.execute(new MessagePrinterTask("Message" + i)); 
    } 
    } 
} 

Tuttavia, se MessagePrinterTask ha autowired dipendenze non saranno configurati entro la primavera perché stiamo istanziare il nostro fagiolo al di fuori del contesto di primavera (almeno questo è come la capisco) anche se Spring fornirà la vera creazione di thread. Se MessagePrinterTask dovesse avere dipendenze autowired, come possiamo ottenere che Spring li riconosca? Ho provato il seguente esempio modificato senza alcun risultato (e sì, autowiring abilitata opportunamente):

import org.springframework.core.task.TaskExecutor; 

public class TaskExecutorExample { 

    @Component 
    private class MessagePrinterTask implements Runnable { 

    @Autowired 
    private autoWiredDependency; 

    public void run() { 
     autoWiredDependency.doNotThrowNullPointerExceptionPlease(); 
    } 

    } 

    private TaskExecutor taskExecutor; 

    public TaskExecutorExample(TaskExecutor taskExecutor) { 
    this.taskExecutor = taskExecutor; 
    } 

    public void printMessages() { 
    for(int i = 0; i < 25; i++) { 
     taskExecutor.execute(new MessagePrinterTask()); 
    } 
    } 
} 

risposta

11

Ci sono due modi penso che si può andare su questo:

a. Fornire le dipendenze al compito - in questo modo:

class MessagePrinterTask implements Runnable { 
    public MessagePrinterTask(ADependency aDependency){ 
     this.aDependency = aDependency; 
    } 


    private ADependency aDependency; 

    public void run() { 
     aDependency.doNotThrowNullPointerExceptionPlease(); 
    } 
} 

E nel tuo TaskExectorExample che può essere il Singleton:

import org.springframework.core.task.TaskExecutor; 

public class TaskExecutorExample { 

    @Autowired private ADependency aDependency; 

    @Autowired 
    public TaskExecutorExample(TaskExecutor taskExecutor) { 
    this.taskExecutor = taskExecutor; 
    } 

    public void printMessages() { 
    for(int i = 0; i < 25; i++) { 
     taskExecutor.execute(new MessagePrinterTask(this.aDependency)); 
    } 
    } 
} 

b. Usando l'annotazione @Configurable sul MesasgePrinterTask, questo inietterà nel dipendenze in MessagePrinterTask anche se viene creata un'istanza al di fuori di un contenitore Spring - ci sono alcune catture nell'uso @Configurable se (richiede AspectJ):

@Configurable 
class MessagePrinterTask implements Runnable { 
+0

Grazie per la risposta rapida Biju. Suggerimento a. è quello che sto facendo attualmente, ma è un po 'fastidioso dal momento che devo mantenere un costruttore più dipendenze autowire in una classe che potrebbe non usarli. Ho visto il suggerimento b. ma non sono sicuro se sia il modo più Spring per portare a termine il compito. Grazie comunque! – Jorge

+0

Ora sto usando @Configurable in quanto batte l'opzione a. La mia applicazione non crea un'istanza di molti thread, quindi è sufficiente. – Jorge

1

È inoltre possibile usa l'annotazione @Async.

public class TaskExecutorExample { 

    @Autowired 
    private MessagePrinterTask task; 

    public void printMessages() { 
     for(int i = 0; i < 25; i++) { 
      task.printMessage(); 
     } 
    } 
} 

@Component 
public class MessagePrinterTask implements Runnable { 

    @Autowired 
    private String message; 

    @Async 
    public void printMessage() { 
     System.out.println(message); 
    } 

} 

Qualsiasi chiamata a printMessage() sarà eseguita in modo asincrono utilizzando un esecutore di default, che è possibile configurare utilizzando il seguente nella vostra configurazione primavera xml.

<task:annotation-driven executor="myExecutor"/> 
<task:executor id="myExecutor" pool-size="5" /> 
Problemi correlati