Frühjahr SimpleAsyncTaskExecutor und ThreadPoolTaskExecutor mit @Async-annotation
Ich habe folgende Konfiguration:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:task="http://www.springframework.org/schema/task"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.0.xsd
http://www.springframework.org/schema/task http://www.springframework.org/schema/task/spring-task-3.0.xsd">
<context:component-scan base-package="com.abc" />
<task:annotation-driven executor="executor"/>
<task:executor id="executor" pool-size="2"/>
</beans>
Dann die folgende Klasse
public class SomeClassImpl implements SomeClass {
@Async
@Override //overridden from the interface
public void doSomething(){
System.out.println("doing something async");
}
}
Test:
@ContextConfiguration("classpath:test-config.xml") //with the xml config above
@RunWith(value = SpringJUnit4ClassRunner.class)
public class SomeClassTest {
@Autowired
private SomeClass someClass;
@Test
public void testSomething() throws Exception {
System.out.println("Calling doSomething");
someClass.doSomething();
Thread.sleep(5000);
}
}
Bei mir lief der test, funktioniert alles wie erwartet. Aber dann befestigte ich den debugger zu Schritt über, was eigentlich passiert, wenn someClass.doSomething() aufgerufen wird und Folgendes ist mir aufgefallen:
Warum ist es, dass 4 threads erstellt werden, die von einem SimpleAsyncTaskExecutor? Ich weiß, dass wenn ich die abnehme, der Testamentsvollstrecker Eigenschaft aus der task:annotation-driven xml-element, das AsyncExecutionInterceptor verwenden die SimpleAsyncTaskExecutor. Da ich aber erklärt haben, eine Aufgabe, Testamentsvollstrecker und verwiesen ihn aus der annotation-driven element, warum ist ein SimpleAsyncTaskExecutor geschaffen?
<task:annotation-driven/>
Oops. Copy-paste-Problem. Ich war mit der Ausführung anderer tests, wenn ich dies Schreibe. Ich habe aktualisiert die xml-Datei.
Also, tun Sie noch beobachten SimpleAsyncTaskExecutor threads mit aktuellen config?
Ja. Das Beispiel in meinem Beitrag ist genau das, was ich sehe. Die async-Methode wird ausgeführt, mit der ThreadPoolTaskExecutor definiert in der XML, aber aus welchem Grund auch immer, es gibt 4 threads gestartet SimpleAsyncTaskExecutor, die nichts zu tun.
Ich habe gerade importiert Ihre config in meiner Umgebung und ich habe nur einen weiteren thread genannt
executor-1
. Ich nehme an, Sie haben eine andere <task:annotation-driven/>
woanders oder haben Sie eine andere Quelle Kontext. Mir ist auch aufgefallen, dass Sie laufen nicht die SomeClassTest in Ihrem eclipse-screenshot.InformationsquelleAutor CAL5101 | 2012-11-15
Du musst angemeldet sein, um einen Kommentar abzugeben.
Erste von allen, wenn Sie der Verwendung von Java 5 und höher (erforderlich für Java-Futures, etc), die Standard-TaskExecutor Umsetzung sollte die ThreadPoolTaskExecutor, was mit Ihrem debug-trace-Ausgabe. Dies ist der thread-manager wird tatsächlich zur Umsetzung Ihrer test-code.
Den SimpleAsyncTaskExecutor wird wahrscheinlich ins Leben gerufen als Teil der Frühjahr /task executor-framework, möglicherweise von einer anderen annotation in den test-Kontext-Datei. Der Spring-container kann starten vier Instanzen der SimpleAsyncTaskExecutor Klasse. Nach Frühling Dokumentation, diese version des TaskExecutor nie wieder benutzt threads, um neuen Anforderungen (es wird einen neuen thread starten):
SimpleAsyncTaskExecutor
Referenz: http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/html/scheduling.html#scheduling-task-executor
Daher könnte dies das Ergebnis von Wechselwirkungen zwischen den test-Kontext und der Spring-container.
Ich glaube, Sie haben einen einzigen thread läuft Ihr test-code in diesem Szenario, das ist, was Sie erwarten, basierend auf einer einzigen Anfrage. Frühjahr TaskExecutor Implementierungen nutzen eine Hilfsklasse namens ConcurrencyThrottleSupport soll der Drosselklappe (limit), die Anzahl der gleichzeitigen threads in der Ausführung. In deinem Fall sollten 2 sein, wie dies durch die pool-size-Eigenschaft. Allerdings führen diese ein test, es sollte nie zuteilen müssen einen weiteren thread, und die trace-Ausgabe stimmt mit dieser.
InformationsquelleAutor pmhargis