인프런 커뮤니티 질문&답변

Truestar님의 프로필 이미지

작성한 질문수

스프링 핵심 원리 - 고급편

@target, @within

이번 예제에서 Config 클래스에 @Configuration 을 적용하니, Proxy 래핑/등록이 안되는것 같습니다.

해결된 질문

작성

·

770

0

강사님 안녕하세요.
저는 지금 예제 구현시 의도와 다르게 약간 틀린 설정으로 생긴
예상밖의 결과로 약간 혼동을 겪고있습니다.

이유는 @Configuration 을 실수로 붙였더니, 아래와 같이
Proxy 가 적용되지 않은 결과가 나옵니다.

  1.  Config 클래스에 아래와 같이 @Configuration 선언시
    @Configuration
    static class Config {
    ...
    ...
    }
      • child.childMethod();
        실행 후 로그 메세지
        : child Proxy=class ...AtTargetAtWithinTest$Child
        (Proxy 적용이 안된 스프링 빈 출력)


      • child.parentMethod();
        Parent 는 프록시 처리가 되지 않아 출력되지 않음


관례처럼 사용해오던 @Configuration 을 지우니 강의 예제결과처럼 정상으로 나옵니다.
(@Import 를 통해 Config 추가 상태)

Aspect 를 빈으로 등록해도 Proxy 변환이 안되는 이 상황이 이해가 되지 않아 부득이하게 질문을 남기게 되었습니다.


질문입니다.

예전 강의에서 @Configuration
등록되는 빈 을 대상으로 싱글톤 후처리를 위해 선언되는 것이라 알고있었습니다.( CGLIB 을 통해 프록시 후처리), 그래서 Aspect 가 당연히 적용될 줄 알았는데 @Configuration 을 붙이니,Proxy  처리가 되지 않더라구요.

아래는 두가지 결과 입니다.

  1. @Configration Config
  2. @Import(Config.class)

@Configuration 선언 시, Proxy 후처리가 되지 않는 기묘한 현상에 대한 이해가 잘 되지 않습니다.
이런 이유로
Config 클래스에 @Configuration 을 쓰지않고, @Import 로 추가하신 이유가 궁금합니다.

읽어주셔서 감사드립니다.

답변 4

9

Truestar님의 프로필 이미지
Truestar
질문자

@SpringBootTest 내에
innerClass @Configuration, AOP설정 - 정리

제가 아는 범위내에서 강사님 답변을 토대로 정리했습니다.


@SpringBootTest 시, @Configuration 설정 주의사항

@SpringBootTest 작성시, 내부 클래스에 @Configuration 을 선언 했다면, 기존에 작성된 어딘가의 의존성을 찾을수 없다거나, 잘 작동하던 기능이 갑자기 작동을 안하는 것을 경험할 것이다. 이 설정으로 생기는 부수효과는 Spring 라이브러리 설정 및, `src/main`모듈의 설정 전체가 무시된다. 이유는, 내부 클래스에 선언된 @Configuration 클래스 경로가 자동으로 컴포넌트스켄 기본패키지로 지정되기 때문.

만약 `src/main`모듈에 AOP 설정을 해놓은 상태라 가정하면, @Configuration 설정 때문에, 스프링 부트를 통한 AOP관련 설정클래스 들 마저 스프링 빈으로 등록되지 않게 된다.
결국, AOP 자체가 동작하지 않게 된다는 것이다.


그렇다면 @SpringBootTest 시점에서
기본 Spring-boot 설정을 유지하며( AOP 설정포함) 추가적으로
테스트용 @Configuration 을 설정하는 방법은?

  1. 내부 설정클래스에 @EnableAspectJAutoProxy 선언 및, 기존모듈의 basePackage 설정 방식
    : 이 방식은, 기존`src/main`모듈설정 따로, AOP 설정 따로, 각각 해주어야 하므로 번거롭다.

  2. `추천!` - @Configuration  ▶  @TestConfiguration 변경(치환)
    내부 설정클래스에 @TestConfiguration 선언을 통해,
    기존 `src/main`모듈의 Spring-boot 설정을 활성화하는 방식.
    : @SpringBootTest `src/main`전체모듈설정 + 테스트 Config 형태로,  
    기존설정 기반 + 추가설정이 가능하다.

 

수정할 부분에 대해 답글 남겨주시면 검토 후, 반영하겠습니다.

6

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. Truestar님

이 문제는 사실 생각하신 것과는 전혀 다른 문제입니다^^

@SpringBootTest를 사용하면서, 그 안에서 내부 클래스로 @Configuration을 사용하게 되면 스프링 부트의 다양한 설정들이 먹히지 않고, @Configuration 안에서만 적용한 설정이 먹히게 됩니다. 이 설정이 우선권을 가지고 가버리기 때문에 스프링 부트의 다른 설정이 적용되지 않습니다. 쉽게 이야기해서 테스트에서는 이 설정만 사용하게 됩니다.

여기서 문제는 스프링 부트가 만들어주는 AOP 관련 기본 클래스들도 스프링 빈으로 등록되지 않고, 결국 AOP 자체가 동작하지 않게 된다는 점입니다. (강의에서 말씀드린 AutoProxy가 있어야 AOP를 적용할 수 있습니다.)

그러면 AOP가 동작하도록 하는 기능들을 등록하면 되겠지요?

바로 @EnableAspectJAutoProxy를 다음과 같이 직접 넣어주시면 됩니다. 그러면 AOP가 적용되면서 정상 동작하게 됩니다.

@EnableAspectJAutoProxy
@Configuration
static class InnerConfig {
}

그런데 이렇게 사용하는 것은 많이 번거롭습니다.

스프링 부트는 스프링 부트의 기본 기능을 설정을 사용하면서 그 위에 원하는 설정을 더하는 방법도 제공합니다.

바로 @TestConfiguration을 사용하면 됩니다.

@TestConfiguration
static class InnerConfig {
}

그러면 스프링 부트 설정을 그대로 다 적용하면서, 그 위에 원하는 클래스만 살짝 올릴 수 있습니다.

도움이 되셨길 바래요^^

Truestar님의 프로필 이미지
Truestar
질문자

오... 너무 감사드려요.. 단번에 이해가 되었습니다.
알려주신 내용은 후속 강의주제인 `Spring-boot 자동화 기능 - AOP 자동화`에 대한 내용이군요!!!
미래에 갔다가 강의맛을 보고 온듯한 느낌같은 느낌...

주신 답변을 토대로 다시 정리해 보겠습니다.
친절하신 답변 고맙습니다😀

0

Truestar님의 프로필 이미지
Truestar
질문자

고맙습니다 강사님! 

1. 실행방법

프로젝트 모듈 폴더구조

  • 03-Spring-core-principles-advanced
      • advanced
      • aop  <
      • proxy

2. 문제 확인 방법

테스트 파일 입니다.

: 테스트파일을 오픈해놓은 상태로 보내드렸지만
안보이시면, 아래 경로를 통해 Test 를 실행할 수 있습니다.

src/test/java/hello.aop.pointcut_expression.AtTarget_AtWithin_Test.java

아래는 해당 테스트 파일 경로 캡쳐입니다.

 

0

김영한님의 프로필 이미지
김영한
지식공유자

안녕하세요. Truestar님

전체 프로젝트를 압축해서 구글 드라이브로 공유해서 링크를 남겨주세요.

구글 드라이브 업로드 방법은 다음을 참고해주세요.

https://bit.ly/3fX6ygx

 

주의: 업로드시 링크에 있는 권한 문제 꼭 확인해주세요

 

추가로 다음 내용도 코멘트 부탁드립니다.

1. 실행 방법을 알려주세요.

2. 어떻게 문제를 확인할 수 있는지 자세한 설명을 남겨주세요.

감사합니다.

 

Truestar님의 프로필 이미지

작성한 질문수

질문하기