관리 메뉴

IT.FARMER

Spring AOP (Aspect Oriented Programming) 본문

Spring/Spring Pure

Spring AOP (Aspect Oriented Programming)

아이티.파머 2022. 6. 8. 13:39
반응형

Spring AOP 에서 Proxy 모드를 사용하는데는 두가지 방법이 있다.

  • JDK Dynamix proxy
    • 인터페에스가 존재해야 한다.
    • 인터페이스를 기준으로 proxy 를 생성한다
    • 리플리케이션을 통해 동적으로 프록시 객체를 생성한다.
  • CGLib Proxy : 구현체만 있어도 된다.
    • <aop:config proxy-target-class=”true” > 설정을 해주어야 한다. 어노테이션으로는 다음과 같다. @EnableAspectJAutoProxy(proxyTargetClass = true)
    • Springboot 에서는 CGLib 라이브러리가 안정화 되었다고 보고 라이브러리가 포함되어 있다.
    • class 상속을 통해 proxy 객체를 생성한다.
    • inferface, class 기준으로 proxy 를 생성한다.
    • 타겟 클레스의 바이트코드를 조적하여 재정의 함으로 final 사용은 불가하다.

Spring paroxyTargetClass 의 의미 ?

스프링에서는 프록시를 구현할때 기존방식처럼 인터페이스를 이용한 JDK Dynamic 을 이용할것인지 또는 해당 클레스 바이트를 직접 조작하여 CGLib proxy 를 사용 할것인지에 대한 옵션을 제공하고 있는데 이것이 proxyTargetClass 이다. true 로 사용하연 클래스를 직접 조작하겠다는 의미로 CGLib Proxy 를 사용한다.

Spring AOP Advice 생명주기

  • Befor
    • target 메소드 호출전에 적용
  • After returning
    • 타겟 메소드 호출후에 적용
  • After Throwing
    • 타겟에서 예외 발생후 적용
  • After
    • 타겟 메호드 호출후 예외 발생 상관 없이 적용
  • Around
    • 타겟 메소드 호출 전/후 에 적용됨
2022-03-25 17:04:30.090 TRACE 40768 --- [    Test worker] o.s.aop.framework.JdkDynamicAopProxy     : Creating JDK dynamic proxy: SingletonTargetSource for target object [skan.aop.MemberServiceImpl@64aad809]

1. JDK Dynamic Proxy 방식 AOP 예제

JDK Dynamic Proxy 방식 으로 개발을 하기 원할때는 몇 가지 설정을 변경해 주어야 한다.
프로퍼티를 spring.aop.proxy-target-class=false 기본으 true 이기때문에 false로 변경 한다. 이렇게 하면 인터페이스에 AOP 의 advice 걸어서 사용 할 수 있다.

application.properties

프로퍼티에서 proxy target class 를 false 로 변경하여 jdk dynamic proxy를 사용하도록 한다.

spring.aop.proxy-target-class=false

logging.level.root=INFO
logging.level.org.springframework.aop=trace

@Retry

인터페이스에 적용할 Advice 용 @annotation 을 생성한다.

@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {

    /**
     * retry 횟수
     */
    int value() default 3;

}

AspectMemberService.java

AOP가 동잘될 지점과 내용을 설정한다.

@Slf4j
@Aspect
@Component
public class AspectMemberService {

    @Before("@annotation(skan.annotation.Retry)")
    public void doSomethingBefore(JoinPoint joinPoint) {
        log.info("------------------------ BEFORE START ");
        log.info("before joinPoint= {}", joinPoint.getKind());
        Arrays.stream(joinPoint.getArgs()).
                map(o -> "+plus")
                .collect(Collectors.toList());
                ;
        log.info("------------------------ BEFORE END ");

    }

    @Around(value ="execution(* skan.aop.MemberService.save(String))" +"@annotation(skan.annotation.Retry)")
    public Object processed(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        log.info("------------------------ AOP-PLAIN  : START ");
        long begin = System.currentTimeMillis();

        log.info("args            = {}",proceedingJoinPoint.getArgs());
        log.info("signature       = {}",proceedingJoinPoint.getSignature());
        log.info("target          = {}",proceedingJoinPoint.getTarget());
        log.info("static part     = {}",proceedingJoinPoint.getStaticPart());
        log.info("kind            = {}",proceedingJoinPoint.getKind());
        log.info("source location = {}",proceedingJoinPoint.getSourceLocation());
        log.info("this            = {}",proceedingJoinPoint.getThis());
        log.info("class           = {}",proceedingJoinPoint.getClass());

        Object retVal = proceedingJoinPoint.proceed(); // 메서드 호출 자체를 감쌈
        log.info("aspect 실행 시간 = {} ", System.currentTimeMillis() - begin);

        log.info("------------------------ AOP-PLAIN  : END ");

        log.info("------------------------ AOP-ANNOTATION VALUE  : START");
        MethodSignature methodSignature =  (MethodSignature) proceedingJoinPoint.getSignature();
        Retry retry = methodSignature.getMethod().getAnnotation(Retry.class);
        log.info("retry count  = {} ", retry.value());
        log.info("------------------------ AOP-ANNOTATION VALUE : END");

        return retVal;
    }

    @AfterReturning(value = "@annotation(skan.annotation.Retry)", returning = "returnObject")
    public void doSomethingAfter(JoinPoint joinPoint, Object returnObject) {
        log.info("------------------------ AFTER  : START ");
        log.info("after returning joinPoint     = {}", joinPoint.getKind());
        log.info("after returning object = {}", returnObject);
        log.info("------------------------ AFTER : END");
    }

    @AfterThrowing(value = "@annotation(skan.annotation.Retry)", throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint , Exception exception) {

        log.error("aop throwing",exception);

    }
}

**MemberService.java**

인터페이스 설정 @Retry 적용

public interface MemberService {

    @Retry
    String save(String test_data);
    @Retry(1)
    int delete(String data) throws Exception;
}

MemberServiceImpl.java

인터페이스를 상속 받은 구현체 비지니스 로직 구현.

@Service
@Slf4j
public class MemberServiceImpl implements MemberService {

    public String save(String data) {
        log.info("data = {}", data);
        return "DATA SAVE SUCCESS";
    }

    public int delete(String data) throws Exception{
        Random random = new Random();
        // try catch block 에 의해 aspectThrowing 은 동작하지 안는다.
        // try-catch block 을 삭제 하면 다시 aspect 에 검사된다.
        //try {
            if (random.nextBoolean()) {
                throw new RuntimeException("delete 예외발생");
            }
            log.info("delete 성공 !!! ");
        //} catch (Exception e) {
        //    e.printStackTrace();
        //}
        return 0;
    }

}

SrpingApplication.java

@Slf4j
@SpringBootApplication
public class SrpingApplication {
    public static void main(String[] args) {
        SpringApplication.run(SrpingApplication.class);
    }
}

MemberServiceImplTest.java

테스트 케이스 생성

@SpringBootTest
class MemberServiceImplTest {
    @Autowired MemberService memberService;

    @Test
    @DisplayName("저장 AOP")
    public void save() throws Exception {
        memberService.save("memeber name");
    }

    @Test
    @DisplayName("예외를 일으켜 AOP 확인하기 ")
    public void aopException() throws Exception {
        memberService.delete("");
    }
}

Dynamic proxy log 확인

정확한 확인을 위해 org.springframework.aop 의 로그 레벨을 trace로 한다.

Creating JDK dynamic 로그에서 해당 문구를 확인 할 수 있다

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.7)

2022-03-25 19:08:31.722  INFO 41947 --- [    Test worker] skan.aop.MemberServiceImplTest           : Starting MemberServiceImplTest using Java 11.0.11 on mezzoui-MacBookPro.local with PID 41947 (started by mezzo-skan in /Users/mezzo-skan/git/progream.study/spring.skan.study/springboot.aop/springboot.default.001)
2022-03-25 19:08:31.723  INFO 41947 --- [    Test worker] skan.aop.MemberServiceImplTest           : No active profile set, falling back to default profiles: default
2022-03-25 19:08:32.028 DEBUG 41947 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public java.lang.Object skan.aop.AspectMemberService.processed(org.aspectj.lang.ProceedingJoinPoint) throws java.lang.Throwable
2022-03-25 19:08:32.029 DEBUG 41947 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public void skan.aop.AspectMemberService.doSomethingBefore(org.aspectj.lang.JoinPoint)
2022-03-25 19:08:32.029 DEBUG 41947 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public void skan.aop.AspectMemberService.doSomethingAfter(org.aspectj.lang.JoinPoint,java.lang.Object)
2022-03-25 19:08:32.036 DEBUG 41947 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public void skan.aop.AspectMemberService.afterThrowing(org.aspectj.lang.JoinPoint,java.lang.Exception)
2022-03-25 19:08:32.156 TRACE 41947 --- [    Test worker] a.AnnotationAwareAspectJAutoProxyCreator : Creating implicit proxy for bean 'memberServiceImpl' with 0 common interceptors and 2 specific interceptors
2022-03-25 19:08:32.158 TRACE 41947 --- [    Test worker] o.s.aop.framework.JdkDynamicAopProxy     : Creating JDK dynamic proxy: SingletonTargetSource for target object [skan.aop.MemberServiceImpl@57cb70be]
2022-03-25 19:08:32.252  INFO 41947 --- [    Test worker] skan.aop.MemberServiceImplTest           : Started MemberServiceImplTest in 0.739 seconds (JVM running for 1.577)
2022-03-25 19:08:32.254  INFO 41947 --- [    Test worker] skan.SrpingApplication                   : init str = {}
2022-03-25 19:08:32.531  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : ------------------------ AOP-PLAIN  : START 
2022-03-25 19:08:32.531  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : args            = memeber name
2022-03-25 19:08:32.532  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : signature       = String skan.aop.MemberService.save(String)
2022-03-25 19:08:32.532  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : target          = skan.aop.MemberServiceImpl@57cb70be
2022-03-25 19:08:32.532  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : static part     = execution(String skan.aop.MemberService.save(String))
2022-03-25 19:08:32.532  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : kind            = method-execution
2022-03-25 19:08:32.533  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : source location = org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint$SourceLocationImpl@28279a49
2022-03-25 19:08:32.533  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : this            = skan.aop.MemberServiceImpl@57cb70be
2022-03-25 19:08:32.533  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : class           = class org.springframework.aop.aspectj.MethodInvocationProceedingJoinPoint
2022-03-25 19:08:32.533  INFO 41947 --- [    Test worker] skan.aop.MemberServiceImpl               : data = memeber name
2022-03-25 19:08:32.534  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : aspect 실행 시간 = 3 
2022-03-25 19:08:32.534  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : ------------------------ AOP-PLAIN  : END 
2022-03-25 19:08:32.534  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : ------------------------ AOP-ANNOTATION VALUE  : START
2022-03-25 19:08:32.534  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : retry count  = 3 
2022-03-25 19:08:32.537  INFO 41947 --- [    Test worker] skan.aop.AspectMemberService             : ------------------------ AOP-ANNOTATION VALUE : END
BUILD SUCCESSFUL in 2s
4 actionable tasks: 4 executed
7:08:32 오후: Task execution finished ':springboot.aop:springboot.default.001:test --tests "skan.aop.MemberServiceImplTest.save"'.

2. CGLib proxy AOP 예제

jdk 다이나믹 프록시와 다르게 인터페이스를 구현하지 않고 오로지 클레스로만 사용한다. 클레스자체가 프록시로 생성됨으로 final 을 사용하면 사용이 불가능 하다.

SpringBoot 에서는 proxyTargetClass 가 기본 true 임으로 프로퍼티를 수정하지 않고 실행한다. @SpringBootApplication 안에 내부를 살펴보면 @EnableAspectJAutoProxy 도 선언되어 있다.

앞서도 이야기 했지만 CGLib proxy 의 가장큰 차이점은 인터페이스를 생성하지 않고 Class 에서 바이트코드를 만들어 proxy 한다느것이다. 즉 inferface를 만들지 않고 Class 만생성하여 advice 를 할 수 있다.

인터페이스가 없음으로 좀더 간결하게 작성가능하다.

**Retry.class**

@Inherited
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Retry {

    /**
     * retry 횟수
     */
    int value() default 3;

}

**AspectMemberService.class**

@Slf4j
@Aspect
@Component
public class AspectMemberService {

    @Before("@annotation(skan.annotation.Retry)")
    public void doSomethingBefore(JoinPoint joinPoint) {
        log.info("------------------------ BEFORE START ");
        log.info("before joinPoint= {}", joinPoint.getKind());
        Arrays.stream(joinPoint.getArgs()).
                map(o -> "+plus")
                .collect(Collectors.toList());
                ;
        log.info("------------------------ BEFORE END ");

    }

    @Around(value ="execution(* skan.aop.MemberService.save(String))" +"@annotation(skan.annotation.Retry)")
    public Object processed(ProceedingJoinPoint proceedingJoinPoint) throws Throwable {

        log.info("------------------------ AOP-PLAIN  : START ");
        long begin = System.currentTimeMillis();

        log.info("args            = {}",proceedingJoinPoint.getArgs());
        log.info("signature       = {}",proceedingJoinPoint.getSignature());
        log.info("target          = {}",proceedingJoinPoint.getTarget());
        log.info("static part     = {}",proceedingJoinPoint.getStaticPart());
        log.info("kind            = {}",proceedingJoinPoint.getKind());
        log.info("source location = {}",proceedingJoinPoint.getSourceLocation());
        log.info("this            = {}",proceedingJoinPoint.getThis());
        log.info("class           = {}",proceedingJoinPoint.getClass());

        Object retVal = proceedingJoinPoint.proceed(); // 메서드 호출 자체를 감쌈
        log.info("aspect 실행 시간 = {} ", System.currentTimeMillis() - begin);

        log.info("------------------------ AOP-PLAIN  : END ");

        log.info("------------------------ AOP-ANNOTATION VALUE  : START");
        MethodSignature methodSignature =  (MethodSignature) proceedingJoinPoint.getSignature();
        Retry retry = methodSignature.getMethod().getAnnotation(Retry.class);
        log.info("retry count  = {} ", retry.value());
        log.info("------------------------ AOP-ANNOTATION VALUE : END");

        return retVal;
    }

    @AfterReturning(value = "@annotation(skan.annotation.Retry)", returning = "returnObject")
    public void doSomethingAfter(JoinPoint joinPoint, Object returnObject) {
        log.info("------------------------ AFTER  : START ");
        log.info("after returning joinPoint     = {}", joinPoint.getKind());
        log.info("after returning object = {}", returnObject);
        log.info("------------------------ AFTER : END");
    }

    @AfterThrowing(value = "@annotation(skan.annotation.Retry)", throwing = "exception")
    public void afterThrowing(JoinPoint joinPoint , Exception exception) {

        log.error("aop throwing",exception);

    }
}

MemberService.java

@Service
@Slf4j
public class MemberService {
    @Retry(2)
    public String save(String data) {
        log.info("data = {}", data);
        return "DATA SAVE SUCCESS";
    }
    @Retry(3)
    public int delete(String data) throws Exception{
        Random random = new Random();
        // try catch block 에 의해 aspectThrowing 은 동작하지 안는다.
        // try-catch block 을 삭제 하면 다시 aspect 에 검사된다.
        //try {
            if (random.nextBoolean()) {
                throw new RuntimeException("delete 예외발생");
            }
            log.info("delete 성공 !!! ");
        //} catch (Exception e) {
        //    e.printStackTrace();
        //}
        return 0;
    }
}

SrpingApplication.java

@Slf4j
@SpringBootApplication
public class SrpingApplication {
    public static void main(String[] args) {
        SpringApplication.run(SrpingApplication.class);
    }
}

CGlib proxy log 확인

o.s.aop.framework.CglibAopProxy 의 로그로 cglib proxy 로 활성화 된것을 확인 할 수있다.

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.7)

2022-03-28 10:01:26.270  INFO 1524 --- [    Test worker] skan.aop.MemberServiceImplTest           : Starting MemberServiceImplTest using Java 11.0.11 on mezzoui-MacBookPro.local with PID 1524 (started by mezzo-skan in /Users/mezzo-skan/git/progream.study/spring.skan.study/springboot.aop/springboot.cglib.aop)
2022-03-28 10:01:26.271  INFO 1524 --- [    Test worker] skan.aop.MemberServiceImplTest           : No active profile set, falling back to default profiles: default
2022-03-28 10:01:26.612 DEBUG 1524 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public java.lang.Object skan.aop.AspectMemberService.processed(org.aspectj.lang.ProceedingJoinPoint) throws java.lang.Throwable
2022-03-28 10:01:26.614 DEBUG 1524 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public void skan.aop.AspectMemberService.doSomethingBefore(org.aspectj.lang.JoinPoint)
2022-03-28 10:01:26.615 DEBUG 1524 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public void skan.aop.AspectMemberService.doSomethingAfter(org.aspectj.lang.JoinPoint,java.lang.Object)
2022-03-28 10:01:26.622 DEBUG 1524 --- [    Test worker] .s.a.a.a.ReflectiveAspectJAdvisorFactory : Found AspectJ method: public void skan.aop.AspectMemberService.afterThrowing(org.aspectj.lang.JoinPoint,java.lang.Exception)
2022-03-28 10:01:26.750 TRACE 1524 --- [    Test worker] a.AnnotationAwareAspectJAutoProxyCreator : Creating implicit proxy for bean 'memberServiceImpl' with 0 common interceptors and 5 specific interceptors
2022-03-28 10:01:26.752 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Creating CGLIB proxy: SingletonTargetSource for target object [skan.aop.MemberServiceImpl@43f9dd56]
2022-03-28 10:01:26.757 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Unable to apply any optimizations to advised method: public int skan.aop.MemberServiceImpl.delete(java.lang.String) throws java.lang.Exception
2022-03-28 10:01:26.757 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Unable to apply any optimizations to advised method: public java.lang.String skan.aop.MemberServiceImpl.save(java.lang.String)
2022-03-28 10:01:26.758 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Found 'equals' method: public boolean java.lang.Object.equals(java.lang.Object)
2022-03-28 10:01:26.758 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Unable to apply any optimizations to advised method: public java.lang.String java.lang.Object.toString()
2022-03-28 10:01:26.759 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Found 'hashCode' method: public native int java.lang.Object.hashCode()
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Unable to apply any optimizations to advised method: protected native java.lang.Object java.lang.Object.clone() throws java.lang.CloneNotSupportedException
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isProxyTargetClass()
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setTargetSource(org.springframework.aop.TargetSource)
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setExposeProxy(boolean)
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isExposeProxy()
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.setPreFiltered(boolean)
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isPreFiltered()
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.removeAdvisor(int) throws org.springframework.aop.framework.AopConfigException
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvisor(org.springframework.aop.Advisor)
2022-03-28 10:01:26.760 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.replaceAdvisor(org.springframework.aop.Advisor,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.removeAdvice(org.aopalliance.aop.Advice)
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract java.lang.String org.springframework.aop.framework.Advised.toProxyConfigString()
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isInterfaceProxied(java.lang.Class)
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public default int org.springframework.aop.framework.Advised.getAdvisorCount()
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract java.lang.Class[] org.springframework.aop.framework.Advised.getProxiedInterfaces()
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract org.springframework.aop.Advisor[] org.springframework.aop.framework.Advised.getAdvisors()
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract org.springframework.aop.TargetSource org.springframework.aop.framework.Advised.getTargetSource()
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2022-03-28 10:01:26.761 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvisor(int,org.springframework.aop.Advisor) throws org.springframework.aop.framework.AopConfigException
2022-03-28 10:01:26.762 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(int,org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException
2022-03-28 10:01:26.762 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract void org.springframework.aop.framework.Advised.addAdvice(org.aopalliance.aop.Advice) throws org.springframework.aop.framework.AopConfigException
2022-03-28 10:01:26.762 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.aopalliance.aop.Advice)
2022-03-28 10:01:26.762 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract int org.springframework.aop.framework.Advised.indexOf(org.springframework.aop.Advisor)
2022-03-28 10:01:26.762 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract boolean org.springframework.aop.framework.Advised.isFrozen()
2022-03-28 10:01:26.762 TRACE 1524 --- [    Test worker] o.s.aop.framework.CglibAopProxy          : Method is declared on Advised interface: public abstract java.lang.Class org.springframework.aop.TargetClassAware.getTargetClass()
2022-03-28 10:01:26.883  INFO 1524 --- [    Test worker] skan.aop.MemberServiceImplTest           : Started MemberServiceImplTest in 0.833 seconds (JVM running for 1.798)
2022-03-28 10:01:26.884  INFO 1524 --- [    Test worker] skan.SrpingApplication                   : init str = {}
2022-03-28 10:01:27.193  INFO 1524 --- [    Test worker] skan.aop.AspectMemberService             : ------------------------ AOP-PLAIN  : START
반응형

'Spring > Spring Pure' 카테고리의 다른 글

Sring boot jpa log 설정  (0) 2022.11.04
Spring AOP Proxy  (0) 2022.06.08