복붙노트

[SPRING] 다른 비동기 메소드에서 호출 된 Spring 비동기 메소드

SPRING

다른 비동기 메소드에서 호출 된 Spring 비동기 메소드

나는 스프링 4를 사용하고 이상한 행동을 발견했다 ... 만약 비동기 메소드를 여러번 호출한다면, 그들은 모두 다른 스레드에서 호출되어 임의의 시간에 완료된다. 하지만 다른 비동기 메서드에서 여러 번 비동기 메서드를 호출하면 순서대로 완료됩니다. 나는 이런 것을 가지고있다 :

@Async
public void nonAsyncMethod() {
  for (int i = 0; i < 30; i++) {
     asyncMethod();
  }
}

@Async
public void asyncMethod() {
   ... something here
}

기본 비동기 실행 프로그램을 사용하고 있습니다. 다른 것을 사용해야합니까? 그러나이 집행자는 모든 스레드를 재사용하지 않고 매번 다른 스레드를 시작하므로 잘되어야합니다. 단지 우연 일 수 있습니까? 하지만 10 번 이상 시도한 후 첫 번째 방법으로 비동기로 되돌아 가면 무작위로 끝납니다.

해결법

  1. ==============================

    1.당신이 설명하는 것은 Spring AOP의 전형적인 함정이다.

    당신이 설명하는 것은 Spring AOP의 전형적인 함정이다.

    간단히 말해, Spring이 비동기 동작을 제공하려면 런타임에 클래스의 프록시를 만들어야합니다. 그러면 프록시는 코드를 호출하기 전 및 / 또는 호출 후에 수행해야하는 작업을 수행합니다. 그러나 귀하의 경우 프록시 메커니즘은 두 번째 방법에 적용되지 않습니다.

    클래스의 빈이 Spring을 통해 다른 컴포넌트로 주입 될 때, Spring은 실제로 프록시를 대신 주입합니다. 따라서 프록시의 관련 메소드가 호출됩니다. 그러나 클래스 내부에서 메소드를 호출 할 때 Spring AOP의 한계는 프록시가 작동하지 않는다는 것을 의미하지만 대신에 추가 기능이없는 일반 메소드가 호출된다.

    이것이 asyncMethod가 호출 된 동일한 클래스의 다른 메소드와 동일한 스레드에서 항상 실행되는 이유입니다.

    Spring 문서의이 부분과 함께이 훌륭한 블로그 게시물을 확인하십시오.

    코드를 리팩토링 할 필요가없는 문제를 해결하는 방법은 여러 가지가 있습니다.하지만 비동기가 무엇이든 상관없이 두 가지 방법 모두에서 작동하도록하려면 리팩토링하는 것이 가장 좋습니다. 두 번째 방법을 다른 클래스로 리팩터링하는 것입니다. .

  2. from https://stackoverflow.com/questions/24898547/spring-async-method-called-from-another-async-method by cc-by-sa and MIT license