2013-07-19 4 views
8

aufrufen Ich bin neu zu asynchronen Aufgabenausführung im Frühjahr, also bitte vergib mir, wenn dies klingt wie eine dumme Frage.Frühling 3: Wie @async annotierte Methoden aus dem TaskExecutor

Ich habe gelesen, dass @ Async-Annotation ab Frühling 3.x auf Methodenebene eingeführt wird, um den Aufruf dieser Methode asynchron auftreten. Ich habe auch gelesen, dass wir den ThreadPoolTaskExecutor in der Spring-Konfigurationsdatei konfigurieren können.

Was ich bin nicht in der Lage zu verstehen, dass, wie aus einem tak Testamentsvollstrecker eine @Async kommentierten Methode aufzurufen suppose läßt - AsyncTaskExecutor

Früher haben wir etwas zu tun, verwendet wie in einer Klasse:

@Autowired protected AsyncTaskExecutor executor; 

und dann

executor.submit(<Some Runnable or Callable task>) 

ich bin nicht in der Lage, die Beziehung zwischen @Async kommentierten Methoden und TaskExecutor zu verstehen.

Ich habe versucht, viel über das Internet zu suchen, konnte aber nichts dazu bekommen.

Kann jemand ein Beispiel für das gleiche bereitstellen.

Antwort

29

Hier ist ein Beispiel für @Async Verwendung:

@Async 
void doSomething() { 
    // this will be executed asynchronously 
} 

Rufen Sie nun diese Methode von einer anderen Klasse, und es wird asynchron ausgeführt. Wenn Sie ein Rückgabewert ein Future

@Async 
Future<String> returnSomething(int i) { 
    // this will be executed asynchronously 
} 

Die Beziehung zwischen @Async und TaskExecutor verwenden möchten ist, dass @Async eine TaskExecutor hinter den Kulissen verwendet. Aus der Dokumentation:

Wenn Sie @Async für eine Methode angeben, wird standardmäßig der Executor verwendet, der wie oben beschrieben an das Element "annotation-driven" übergeben wird. Das Wertattribut der @ Async-Annotation kann jedoch verwendet werden, wenn angegeben werden muss, dass beim Ausführen einer bestimmten Methode ein anderer Executor als der Standardwert verwendet werden soll.

So ein Default-Executor einzurichten, fügen Sie diese zu Ihrer Feder Config

<task:annotation-driven executor="myExecutor" /> 

oder eine bestimmte Testamentsvollstrecker für den einmaligen Gebrauch zu verwenden versuchen

@Async("otherExecutor") 

Siehe http://docs.spring.io/spring/docs/3.2.x/spring-framework-reference/html/scheduling.html#scheduling-annotation-support-async

+0

ich auch die Dokumentation lesen zu starten, aber ich verstehe nicht ganz, wie das Runnables bezieht? Muss ich etwas mit Runnable markieren und eine run-Methode implementieren oder wird das nicht benötigt? –

+0

Sie müssen nicht. Markieren Sie einfach die Methode, die Sie asynchron mit @Async ausführen möchten, und wenn Sie sie aufrufen, sollte sie asynchron ausgeführt werden. – Planky

+0

@Planky Das ist großartig. Aber wenn ich dasselbe mache, benutze eine void main und einfachste Spring-Anwendung, indem ich bean als ApplicationContext = new ClassPathXml ...() erhalte. und den Async-Aufruf ausführen. Es ruft die Methode in einem separaten Thread auf, bis das in Ordnung ist. Aber das Programm ist nicht beendet, ich meine nach der Ausführung der letzten Zeile des Hauptprogramms ist noch am Leben. Ich habe versucht, Keep-Alive auf 2 Sekunden zu setzen, aber vergebens. Ich habe das Programm im Run-Modus nicht im Debug-Knoten ausgeführt. Irgendein Einblick darauf? Wenn Sie möchten, kann ich den Code in separaten QSTN veröffentlichen. – anirban

0

In der Config-Datei sollte man eine Annotation-gesteuerte Aufgabe mit dem Thread-Pool-Namen und der Methode mit @ Async (Pool-Name) wil erwähnen Ich werde als Teil dieses Pools ausgeführt. Dadurch wird eine Proxyklasse für die Instanz mit der Async-Annotation erstellt und für jeden Thread ausgeführt.

+0

klingt eher wie ein Kommentar als eine Antwort. Könnten Sie ein bisschen mehr angeben? –

+0

Ja es ist ein Kommentar, Planky hat bereits die Antwort gegeben. –

0

Sie können Ihrer Anwendungsart und dem folgenden Anwendungskontext @Async hinzufügen.

<task:annotation-driven executor="asynExecutor"/> 
    <task:executor id="asynExecutor" pool-size="5" /> 
1

vollständiges Beispiel

  1. Config Frühling

    @Configuration   
    @EnableAsync   
    @ComponentScan("com.async") 
    public class AppConfig { 
    
        @Bean 
        public AsyncManager asyncManger() { 
         return new AsyncManager(); 
        } 
    
        @Bean 
        public AsyncExecutor asyncExecutor() { 
         return new AsyncExecutor(); 
        } 
    } 
    
  2. Exekutor-Klasse erstellt haben Executor i erstellt, so dass Federpflege Thread-Management übernimmt.

    public class AsyncExecutor extends AsyncConfigurerSupport { 
    
        @Override 
        public Executor getAsyncExecutor() { 
         ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); 
         executor.setCorePoolSize(2); 
         executor.setMaxPoolSize(2); 
         executor.setQueueCapacity(500); 
         executor.setThreadNamePrefix("Violation-"); 
         executor.initialize(); 
         return executor; 
        } 
    } 
    
  3. Erstellen Sie einen Manager.

    public class AsyncManager { 
    
        @Autowired 
        private AsyncService asyncService; 
    
        public void doAsyncTask(){ 
         try { 
          Map<Long, ViolationDetails> violation = asyncService.getViolation(); 
          if(!org.springframework.util.CollectionUtils.isEmpty(violation)){ 
           violation.entrySet().forEach(violationEntry -> {System.out.println(violationEntry.getKey() +"" +violationEntry.getValue());}); 
          } 
          System.out.println("do some async task"); 
         } catch (Exception e) { 
         } 
    
        } 
    } 
    
  4. Konfigurieren Sie Ihre Serviceklasse.

    @Service 
    public class AsyncService { 
    
        @Autowired 
        private AsyncExecutor asyncExecutor; 
    
        @Async 
        public Map<Long,ViolationDetails> getViolation() { 
         // TODO Auto-generated method stub 
         List<Long> list = Arrays.asList(100l,200l,300l,400l,500l,600l,700l); 
         Executor executor = asyncExecutor.getAsyncExecutor(); 
         Map<Long,ViolationDetails> returnMap = new HashMap<>(); 
         for(Long estCode : list){ 
          ViolationDetails violationDetails = new ViolationDetails(estCode); 
          returnMap.put(estCode, violationDetails); 
          executor.execute((Runnable)new ViolationWorker(violationDetails)); 
         } 
         return returnMap;  
        } 
    } 
    class ViolationWorker implements Runnable{ 
    
        private ViolationDetails violationDetails; 
    
        public ViolationWorker(ViolationDetails violationDetails){ 
         this.violationDetails = violationDetails; 
        } 
    
        @Override 
        public void run() { 
         violationDetails.setViolation(System.currentTimeMillis()); 
         System.out.println(violationDetails.getEstablishmentID() + " " + violationDetails.getViolation()); 
        } 
    } 
    
  5. Modell.

    public class ViolationDetails { 
        private long establishmentID; 
        private long violation; 
    
    
        public ViolationDetails(long establishmentID){ 
         this.establishmentID = establishmentID; 
        } 
    
        public long getEstablishmentID() { 
         return establishmentID; 
        } 
        public void setEstablishmentID(long establishmentID) { 
         this.establishmentID = establishmentID; 
        } 
        public long getViolation() { 
         return violation; 
        } 
        public void setViolation(long violation) { 
         this.violation = violation; 
        } 
    
    } 
    
  6. -Test

    public class AppTest { 
        public static void main(String[] args) throws SQLException { 
         AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext(); 
         ctx.register(AppConfig.class); 
         ctx.refresh(); 
    
         AsyncManager task= ctx.getBean(AsyncManager.class); 
         task.doAsyncTask(); 
        } 
    } 
    
Verwandte Themen