• 카테고리

    질문 & 답변
  • 세부 분야

    백엔드

  • 해결 여부

    미해결

AOP(TimeTraceAop)를 @Component 로 선언 vs SpringConfig에 @Bean으로 등록

20.08.05 17:54 작성 조회수 2.87k

40

안녕하세요. 김영한 팀장님, 

AOP(TimeTraceAop)를 @Component로 선언하지 않고

SpringConfig에 @Bean으로 등록할 수 있다고 설명하셨는데 실제로 코드를 돌려보면 빈 순환 참조 에러가 발생합니다.

강의대로 @Component로만 선언하면 문제가 없는데

왜 순환참조가 나는지 질문드립니다.

감사합니다.

The dependencies of some of the beans in the application context form a cycle:

   memberController defined in file [~~~\out\production\classes\com\example\springexample\controller\MemberController.class]

      ↓

   memberService defined in class path resource [com/example/springexample/SpringConfig.class]

┌─────┐

|  timeTraceAop defined in class path resource [com/example/springexample/SpringConfig.class]

답변 11

·

답변을 작성해보세요.

96

안녕하세요. raifado님 좋은 질문입니다.

직접 @Bean으로 등록했을 때 순환참조가 발생하는 이유는 다음과 같습니다.

@Configuration

public class SpringConfig {

    @Bean
    public TimeTraceAop timeTraceAop() {
        return new TimeTraceAop();
    }
}

@Aspect
public class TimeTraceAop {

    @Around("execution(* hello.hellospring..*(..))")
    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable { }
}

TimeTraceAop의 AOP 대상을 지정하는 @Around 코드를 보시면, SpringConfig의 timeTraceAop() 메서드도 AOP로 처리하게 됩니다. 그런데 이게 바로 자기 자신인 TimeTraceAop를 생성하는 코드인 것이지요. 그래서 순환참조 문제가 발생합니다.

반면에 컴포넌트 스캔을 사용할 때는 AOP의 대상이 되는 이런 코드 자체가 없기 때문에 문제가 발생하지 않았습니다.

그러면 AOP 설정 클래스를 빈으로 직접 등록할 때는 어떻게 문제를 해결하면 될까요? 바로 다음과 같이 AOP 대상에서 SpringConfig를 빼주면 됩니다.

@Aspect
public class TimeTraceAop {


    @Around("execution(* hello.hellospring..*(..)) && !target(hello.hellospring.SpringConfig)")

    //@Around("execution(* hello.hellospring..*(..))")

    public Object execute(ProceedingJoinPoint joinPoint) throws Throwable {...}

}

도움이 되셨길 바래요^^

박종웅님의 프로필

박종웅

2022.07.27

감사합니다!!

손승기님의 프로필

손승기

2023.08.29

완벽히 이해했습니다. 감사합니다!

5

다알님의 프로필

다알

2022.05.18

스프링부트 2.1 부터는 overriding 옵션이 false로 default 설정이 된다고 하네요.

https://n1tjrgns.tistory.com/172

 

SpringConfig.java에서 "@Bean public TimeTraceAop"  만들 때는

"@Component public class TimeTraceAop " 여기서  추가로 Bean이 

중복 생성되므로 둘 중 한쪽 Bean은 제거해야 합니다.
("스프링입문_강의자료.pdf" 의 61쪽에  "@Component @Aspect public class TimeTraceAop" 만 있고 SpringConfig.java에 "@Bean public TimeTraceAop" 을 생성하지 않았네요.  )


SpringConfig.java에서 "@Bean public TimeTraceAop" 사용하려면  @Component 삭제 하거나 

application.properties의

spring.main.allow-bean-definition-overriding=true

추가 하면 된다고 하네요.

레녹스님의 프로필

레녹스

2023.03.19

뒤늦게 합류한 사람인데 다알님 댓글로 해결했어요

감사합니다

1

raifado님의 프로필

raifado

질문자

2020.08.06

아 이해되었습니다~! 감사합니다.

0

Eunhye J님의 프로필

Eunhye J

2022.02.16

같은 현상에 대해 해결 되었습니다. 감사합니다!

0

김진완님의 프로필

김진완

2021.12.03

같은 현상이 있어, 질문 올리려다 찾았습니다.

감사합니다!

0

강대현님의 프로필

강대현

2021.09.22

같은거 찾고있었는데 감사합니다

0

Hyojoong Chang님의 프로필

Hyojoong Chang

2021.07.01

저도 이거 찾고 있었는데 도움이 되었습니다.

감사합니다.

0

YG K님의 프로필

YG K

2021.03.17

순환참조 문제가 발생한 점을 캐치하신 점도 본받아야겠습니다.

0

얼티밋님의 프로필

얼티밋

2021.02.04

우와 한참찾았는데 감사합니다 !!

0

이지현님의 프로필

이지현

2021.01.25

저도 같은 고민인데 감사합니다~

0

임현강님의 프로필

임현강

2020.12.29

같은 고민을 하고 있었는데 이 질문, 답변을 통해 해결했습니다. 감사합니다.