문제 상황
•
어떤 것을 하려다가 문제가 발생했는가?
◦
본 서버에 Spring Boot Application 실행 실패 발생 🫠
•
발생한 환경, 프로그램
◦
prod에서만
•
발생한 문제(에러)
◦
AopConfigException
로그
원인
•
추정되는 원인
◦
몰라요.. 모르겠어요.. dev에서 수없이 테스트해봤는데 이런건 처음본단말임!!
◦
로그만 봤을 땐 final class로 선언한거 없는데 뭐지?
•
실제 원인
◦
AOP의 광범위한 포인트컷으로 인한 Spring security 프록시 객체와의 충돌
최종 해결
•
최종 해결을 위한 시행착오(optional)
◦
우선 초 당황.. 진짜 한번도 본 적 없는 에러인데 왜 하필 갑자기 본 서버에 배포하려할 때 발생한건지 감이 안왔는데
일단 AopConfigException 이라고 로그에 적혀있으니 AOP 설정 클래스들을 먼저 확인 → AdminApiLogAspect 클래스가 prod 환경에서만 빈으로 등록되고 있어서 local, dev 환경에서는 해당 에러가 발생하지 않았었음..
Profile 어노테이션 내부 value를 local로 변경하고 테스트해봤을 때 동일한 에러가 발생했으니 이 클래스를 빈으로 등록하다 발생한 에러인게 확정 크아악 이걸 테스트 때 확인을 안해보다니ㅠ
◦
로그를 읽어보면
Cannot subclass final class org.springframework.security.config.annotation.method.configuration.PrePostMethodSecurityConfiguration
Java
복사
◦
Spring AOP가 해당 클래스를 프록시로 감싸려고 했지만, 대상 클래스가 final 이라서, 서브클래싱을 할 수 없어 실패했다고 한다.
1.
Spring AOP(특히 CGLIB)는 프록시를 만들기 위해 클래스의 서브클래스를 생성한다
2.
그런데 final 클래스는 상속이 불가능하므로, CGLIB 방식의 프록시 생성에 실패한다
3.
PrePostMethodSecurityConfiguration 은 Spring Security 내부의 클래스이며, 원래는 AOP 프록시 대상이 되어서는 안된다.
•
해결방법
◦
결국 원인은
AOP의 포인트컷이 너무 광범위한 타겟을 대상으로 지정 → Spring Security 관련 클래스까지 타겟팅 → final class로 선언된 security 클래스까지 포함 → 프록시 만들려다 실패
◦
포인트컷 범위 축소를 하면 된다..
◦
기존
private final static String ADMIN_CUD_POINTCUT =
"@target(org.springframework.web.bind.annotation.RestController) &&" +
"!@annotation(org.springframework.web.bind.annotation.GetMapping)";
Java
복사
◦
변경
private final static String ADMIN_CUD_POINTCUT =
"@target(org.springframework.web.bind.annotation.RestController) && " +
"!@annotation(org.springframework.web.bind.annotation.GetMapping) && " +
"within(org.ftclub.cabinet.*.controller.*)"; // 특정 패키지로 제한
Java
복사
빈 등록을 실행환경별로 다르게 해놨는지 잘 확인하자..