Spring 주해@Async 에 대한 기타 주해 실효 해결

3471 단어 Spring@Async
개술
앞의 글 에 서 는 빈 에 자신 을 주입 하고@Async 와@Transaction 이 있 으 면@Autowire 를 사용 하여 자신 을 주입 하면 순환 의존 을 알 리 고 BeanFactory Aware 를 사용 하여 자신 을 주입 하면@Transaction 을 무효 화 할 수 있다 고 소개 했다.예 를 들 면:

@Service
public class MyService implements BeanFactoryAware{
 private MyService self;
 
 //      
 @Transactional
 public void notWork() {
  ...
 }
 
 @Async
 public Future async(){
  ...
 }
 
 
 @Override
 public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
  self= beanFactory.getBean(MyService.class);
 }
}
그 때 는 간단하게 말 했 을 뿐 인 데,이 글 은 왜 효력 을 잃 었 는 지 소개 하 는 것 이다.
일반적 상황
위의 상황 을 조성 하려 면 다음 과 같은 조건 을 만족 시 켜 야 한다.
  • @Async 와 다른 유사 한@Transaction 주해 가 있 습 니 다
  • 자신의 종 류 는 BeanFactory Aware 에서 BeanFactory 를 통 해 자신 을 얻는다
  • 결과:@Async 를 제외 한 주 해 는 유효 하지 않 습 니 다.다음 그림 과 같 습 니 다.

    정상 적 인 대 리 는 다음 그림 이 어야 합 니 다.

    원인.
    먼저 생각 나 는 것 은@Async 주해 의 처리 방식 이 다른 것 과 다 를 수 있 습 니 다.AsyncAnnotation BeanPostProcessor 의 실현 에서(구체 적 인 코드 는 부모 클래스 Abstract Advising BeanPostProcessor)문 제 를 발 견 했 습 니 다.
    정상 적 인 상황 에서 들 어 온 bean 은 이미 대리 되 는 동적 대리 류 이 고 효력 을 잃 었 을 때 들 어 온 실제 클래스 입 니 다.다음 과 같 습 니 다.

    그 다음 에 코드 를 분석 하고 실제 클래스 라면 69 줄 까지 갔 을 때 true 로 되 돌아 가@Aysnc 의 Advisor 를 동적 이치 에 추가 합 니 다.실제 클래스 라면 83 줄 까지 가면 프 록 시 클래스 를 만 들 고@Aysnc 의 advisor 만 동적 에이전트 에 추가 합 니 다.예 를 들 어@Transaction 은 실 효 됩 니 다.
    왜 대리 류 가 아니 야?
    사실 유일한 차이 점 은 빈 팩 터 리 어 웨 어 에서 빈 팩 터 리 를 통 해 자신 을 얻 었 는 지 여부 다.그런데 왜 BeanFactory 를 사용 하여 자신 을 얻 었 습 니까?후속 BeanPostProcessor 에 서 는 대리 가 아 닙 니까?Spring@Transaction 로드 메커니즘 을 잘 알 고 있다 면@Transaction,@Retryable 주해 의 동적 에이전트 생 성 은 AnnotationAware Aspect JAuto ProxyCreator 에서 만 들 어 졌 다 는 것 을 알 수 있 습 니 다.debug 를 통 해 AnnotationAware Aspect JAuto Proxy Creator 를 거 친 후에 우리 의 동적 대 리 는 추가 되 지 않 았 다 는 것 을 알 게 되 었 습 니 다.
    다시 한 번 AnnotationAwareaspectJAuto Proxy Creator 의 실현 을 살 펴 보 았 으 나 그 를 통 해 대리 류 를 만 들 지 못 했다.그 이 유 는 미리 노출 된 지도 에'마 이 서비스'가 있다 는 것 이다.

    그 는 언제 폭로 되 었 습 니까?사실은
    
    @Override
    public void setBeanFactory(BeanFactory beanFactory) throws BeansException {
     self= beanFactory.getBean(MyService.class);
    }
    그러면 모든 것 이 밝 혀 졌 습 니 다.인 스 턴 스 MyService 에서 BeanFactory Aware 를 촉발 시 켰 습 니 다.beanFactory.getBean(MyService.class)을 통 해.프 록 시 클래스(tips:현재 프 록 시 클래스 는@Async 의 Adivisor 를 포함 하지 않 습 니 다)를 만 들 었 습 니 다.현재 Spring 은 MyService 라 는 Bean 을 만 들 고 있 기 때문에 BeanFactory 에 넣 지 않 았 습 니 다.그리고 우 리 는 이 과정 에서 또 한 번 beanFactory.getBean(My Service.class)을 촉발 시 켰 다.프 록 시 를 만 들 고 돌아 온 후 미리 노출 된 맵 에 가입 하 였 습 니 다.뒤의 일련의 문 제 를 야기 하 다.뭔 가 꼬 인 것 같 아.그림 을 보고 말 하기:
    정상 적 인 상황 은 다음 과 같은 절차 여야 한다.

    이상 한 상황 은 이렇다.

    작은 매듭
    정상 적 인 상황 에서@Autowire 를 사용 하여 주입 합 니 다(Autowire 를 사용 하면 상기 상황 은 순환 의존 도 를 직접 던 집 니 다).물론 문제 가 생 겼 다 고 해서 놓 쳐 서 는 안 된다.그 이 유 를 알 아야 한다!
    이상 이 바로 본 고의 모든 내용 입 니 다.여러분 의 학습 에 도움 이 되 고 저 희 를 많이 응원 해 주 셨 으 면 좋 겠 습 니 다.

    좋은 웹페이지 즐겨찾기