2017-12-18 33 views
0

@Asyncメソッドで@Afterと@Aroundを使用することはできますか?
は、私はこのような注釈の両方で試してみました:一部は、メソッドの終了前に呼び出されAsyncメソッドでのSpring AOPの使用

@Override 
@SetUnsetEditingFleet 
public void modifyFleet(User user, FleetForm fleetForm) throws Exception{ 
    databaseFleetsAndCarsServices.modifyFleet(user, fleetForm); 
} 

@Around("@annotation(SetUnsetEditingFleet) && args(user, fleetForm)") 
public void logStartAndEnd(ProceedingJoinPoint pjp, User user, FleetForm fleetForm) throws Throwable{ 
    fleetServices.setEditingFleet(fleetForm.getIdFleet()); 
    for(Car car : carServices.findByFleetIdFleet(fleetForm.getIdFleet())){ 
     carServices.setEditingCar(car.getIdCar()); //Set cars associated with the fleet 
    } 
    pjp.proceed(); 
    fleetServices.unSetEditingFleet(fleetForm.getIdFleet());  
    for(Car car : carServices.findByFleetIdFleet(fleetForm.getIdFleet())){ 
     carServices.unSetEditingCar(car.getIdCar()); //Unset cars associated with the fleet 
    } 
} 

@Override 
@Async 
@Transactional(rollbackFor=Exception.class) 
public void modifyFleet(User currentUser, FleetForm fleetForm) throws Exception { 
    //method instructions 

後。 @After@Before注釈でも試したところ、結果は同じです。

可能かどうかご存知ですか?

+0

処理が新しいスレッドにディスパッチされたため、メソッドが終了しました。したがって、呼び出しコードの場合、メソッドの実行は終了しました。だからあなたはそれを使うことができますが、あなたはそれを使いたいものではありません。 –

+0

したがって、 '@ Before'だけが使用できます。' @ After'部分は、新しいスレッドの開始後に呼び出され、最後には呼び出されません。それが正しいか? – luca

+2

いいえ、メソッドの最後に呼び出されます。メソッドは、スレッドが開始されるとすぐに終了します。呼び出しコードの場合、メソッドの実行は終了します。 –

答えて

0

@Afterはまだ完了していないため@Ayncで正しく動作しません。これを解決するには、非同期メソッドの場合はvoidの代わりにCompletableFutureを返し、コールバックメソッドの場合はロジックを処理します。ここでのテストなしでは、例があります:

@Around("@annotation(AsyncBeforeAfter)") 
    public void asyncBeforeAfter(ProceedingJoinPoint pjp) throws Throwable{ 
     // before work 
     Object output = pjp.proceed(); 
     CompletableFuture future = (CompletableFuture) output; 
     future.thenAccept(o -> { 
      // after work 
     }); 

    } 

    @Override 
    @Async 
    @AsyncBeforeAfter 
    @Transactional(rollbackFor=Exception.class) 
    public CompletableFuture<String> modifyFleet(User currentUser, FleetForm fleetForm) throws Exception { 
     return CompletableFuture.supplyAsync(() -> { 
      //method instructions 
      return "done"; 
    }); 
    } 
関連する問題