@RequestMapping에 private을 사용하면?

sonarQube의 java rule들 둘러보다가 흥미로운 내용을 발견했다.

 

“@RequestMapping” methods shoud be “public”

 

거의 본능적으로 public 으로 선언하지, private으로 선언하면 어떠한 일이 일어날지 생각해 본 적이 없었다.

private으로 선언 가능한 메소드라면 구지 public을 사용할 이유가 없다.

private으로 바꾸어 보아도 url은 정상적으로 매핑된다(물론 @GetMapping, @PostMapping등도 마찬가지).

그러면 왜 작동을 하는데 문제가 없어보이지만 private으로 선언하지 말라는 것일까?

 

먼저 해당 메소드들은 Spring에서 reflection을 사용해 불러오기 때문에 가시성과는 무관하다.

…because Spring invokes such method via reflection

private, public, protected 뭐든 기능자체는 수행된다.

 

문제는 다른데에 있다.

… private, @RequestMapping method by making it @Secured… it will still be called, whether or not the user is authorized to access it. That’s because AOP proxied are not applied to non-public methods.

AOP 프록시 자체가 public이 아닌 메소드에는 작동하지 않는다.

@Secured나 @PreAuthorize 같은 기능들이 수행되지 않는다.

겉으로 문제없어 보이고, Runtime 시에 error도 나지 않지만 치명적인 문제가 될 수 있다.

 

조금 더 들여다 보자.

  

Spring AOP - Supported Pointcut Designators

Due to the proxy-based nature of Spring’s AOP framework, protected methods are by definition not intercepted, neither for JDK proxies (where this isn’t applicable) nor for CGLIB proxies (where this is technically possible but not recommendable for AOP purposes). As a consequence, any given pointcut will be matched against public methods only!

If your interception needs include protected/private methods or even constructors, consider the use of Spring-driven native AspectJ weaving instead of Spring’s proxy-based AOP framework. This constitutes a different mode of AOP usage with different characteristics, so be sure to make yourself familiar with weaving first before making a decision.

 

proxy-based AOP는 public이 아니면 작동하지 않는다.

public이 아닌곳에 관점지향적 접근이 필요하다면 AspectJ를 고려해보자.