카테고리 없음

유형이없는 args 지정자를 사용하여 포인트 컷을 생성하면 BeanCurrentlyInCreationException이 발생합니다.

기록만이살길 2021. 2. 19. 16:13
반응형

유형이없는 args 지정자를 사용하여 포인트 컷을 생성하면 BeanCurrentlyInCreationException이 발생합니다.

질문(문제점):

유형을 제공하지 않고 지정자 사용하여 Spring AOP작성하려고 할 때를 사용하면 다음으로 시작하는 일련의 예외가 발생합니다.PointcutargsBeanCurrentlyInCreationException

object _001_Spring_AOP_Pointcut_Args_NoArgs {

    open class BeanA {
        open fun m() {
            println("BeanA#m()")
        }
    }

    @Aspect
    class AspectA {
        @Pointcut("args()")
        private fun pc_noArgs() = Unit

        @After("sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs.AspectA.pc_noArgs()")
        private fun ac_noArgs() = println("ac_noArgs")
    }

    @Configuration
    @EnableAspectJAutoProxy(proxyTargetClass = true)
    open class Config {
        @Bean
        open fun beanA(): BeanA = BeanA()

        @Bean
        open fun aspectA(): AspectA = AspectA()
    }

    fun runJava() {
        AnnotationConfigApplicationContext(Config::class.java)
    }

}

실행 방법

    @Test
    fun test_run() {
        _001_Spring_AOP_Pointcut_Args_NoArgs.runJava()
    }

예외 요약

컨텍스트 초기화 중 예외 발생-새로 고침 시도 취소 : org.springframework.beans.factory.BeanCreationException : sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs $ Config에 정의 된 이름이 'beanA'인 빈 생성 오류 : 팩토리 메서드를 통한 빈 인스턴스화 실패; 중첩 된 예외는 org.springframework.beans.BeanInstantiationException입니다. [sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs $ BeanA]를 인스턴스화하지 못했습니다. 팩토리 메소드 'beanA'에서 예외가 발생했습니다. 중첩 된 예외는 org.springframework.beans.factory.BeanCreationException : sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs $ Config에 정의 된 이름이 'aspectA'인 빈 생성 오류 : 팩토리 메서드를 통한 빈 인스턴스화 실패; 중첩 된 예외는 org.springframework.beans.BeanInstantiationException입니다. 인스턴스화 실패 [sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs $ AspectA] : 팩토리 메소드 'aspectA'에서 예외가 발생했습니다. 중첩 된 예외는 org.springframework.beans.factory.BeanCurrentlyInCreationException : 이름이 'aspectA'인 Bean 생성 오류 : 요청 된 Bean이 현재 생성 중입니다. 확인할 수없는 순환 참조가 있습니까?

해결방안:

args()execution(* *())

이것은 매개 변수없이 모든 메소드를 가로채는 특이한 방법입니다. 차라리 더 명확하게 만들고 execution(* *())대신 사용 합니다. 혹시 AspectJ를 봄 AOP에서 마이그레이션하는 경우, 당신은 알 수 args()예를 들어,이 경기를 포인트 컷의 모든 종류의 call, initialization, preinitialization, staticinitialization, get매개 변수없이 생성자 호출 / 실행.

Pointcut 범위 지정

여기 Spring AOP에서 문제는 또 다른 문제 일 수 있습니다. 포인트 컷이 너무 광범위합니다. Spring Bean, Spring 또는 타사 클래스 자체의 많은 조인 포인트와 일치합니다. 따라서 pointcut의 범위를 제한하고 싶습니다. 예 :

execution(* *()) && within(my.own.package.**)

포인트 컷에서 정규화 된 클래스 이름을 사용하지 않는 경우

BTW, 포인트 컷이 그것을 사용하는 어드바이스와 동일한 클래스에서 정의 된 경우, 정규화 된 클래스 이름을 사용할 필요가 없습니다.

@After("sero4.spring.z_added._001_Spring_AOP_Pointcut_Args_NoArgs.AspectA.pc_noArgs()")

당신은 사용할 수 있습니다

@After("pc_noArgs()")

인라인 포인트 컷

다른 조언에서 동일한 포인트 컷을 재사용 할 계획이 없다면 @Pointcut, 다음과 같은 인라인 포인트 컷을 제거 하고 정의하십시오.

@After("execution(* *()) && within(my.own.package.**)")

조언은 public

@Pointcut다른 클래스에서 참조하지 않는 경우 메서드를 private 으로 정의하는 것은 괜찮지 만 @After조언은 public이어야합니다. Spring AOP에서 작동 할 수 있지만 규칙에 위배됩니다. 다시 말하지만, AspectJ로 마이그레이션 한 적이 있다면 AspectJ 어드바이스가 공개되어야하므로 컴파일 오류가 발생할 수도 있습니다.

65742621
반응형