2012-08-02 14 views
5

Według Spring's documentation drogę do korzystania z TaskExecutor się następująco:W jaki sposób mogę wyposażyć w utworzony wątek 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)); 
    } 
    } 
} 

Jednak jeśli MessagePrinterTask został autowired zależności nie zostaną skonfigurowane do wiosny, ponieważ jesteśmy instancji naszą fasolkę poza kontekstem sprężyny (przynajmniej to, jak to rozumiem), mimo że Spring zapewni rzeczywiste tworzenie wątków. Jeśli MessagePrinterTask miałby mieć autowyprobowane zależności, w jaki sposób sprawić, by Spring je rozpoznał? Próbowałem poniższy zmodyfikowany przykład bezskutecznie (i tak, autowiring jest prawidłowo włączony):

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()); 
    } 
    } 
} 

Odpowiedz

11

Istnieją dwa sposoby, myślę, że można iść na ten temat:

a. Zapewnić zależności do tego zadania - w ten sposób:

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


    private ADependency aDependency; 

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

I w TaskExectorExample który może być pojedyncza:

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. Korzystanie @Configurable adnotacji na MesasgePrinterTask, to wstrzyknąć w zależności do MessagePrinterTask mimo że jest tworzony poza Spring Container - istnieją pewne połowy w użyciu @Configurable chociaż (wymaga AspectJ):

@Configurable 
class MessagePrinterTask implements Runnable { 
+0

Dzięki za szybką odpowiedź Biju. Sugestia a. jest to, co obecnie robię, ale jest to trochę denerwujące, ponieważ muszę utrzymywać konstruktora i zależności od autowire w klasie, która może ich nie używać. Widziałem sugestię b. ale nie jestem pewien, czy jest to najbardziej wiosenny sposób na wykonanie tego zadania. W każdym razie dzięki! – Jorge

+0

Używam teraz opcji @Configurable jako, że pobudza opcję a. Moja aplikacja nie tworzy instancji wielu wątków, więc wystarczy. – Jorge

1

Można również użyj adnotacji @Aynchron.

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); 
    } 

} 

Każde wywołanie printMessage() będą wykonywane asynchronicznie za pomocą domyślnej wykonawcę, który można skonfigurować przy użyciu następujących Wiosna w xml config.

<task:annotation-driven executor="myExecutor"/> 
<task:executor id="myExecutor" pool-size="5" /> 
Powiązane problemy