본문 바로가기
Spring

[Spring] @Transactional에 private 접근 제한자가 불가능한 이유

by asdft 2024. 1. 25.

개요

Socket 사이드 프로젝트를 진행하던 중 git에 push를 하기 전에 외부 패키지에서 사용할 일이 없는 메소드의 경우 private로 접근제한자를 설정하기 위해서 살펴보던 와중에, 아래와 같이 @Transaction이 붙은 메소드는 private 접근 제한자가 불가능한것을 발견했다.

 

그리고 아래와 같은 오류메시지를 알려줬다.

Methods annotated with '@Transactional' must be overridable.

 

@Transactional은 spring AOP를 사용하여 구현되는데 기본적으로 AOP는 proxy패턴 을 사용하여 구현이 된다. 

 

결론부터 말하자면,
1. spring의 @Transactional은 proxy로 동작한다.
2. 그러므로 private 사용이 불가하다.

 

그렇다면 과연 proxy패턴이 어떻게 동작하는지 또한 Spring AOP란 무엇인지 알아보자.


Proxy ( 프록시 패턴 )

  • 특정 객체에 대한 접근을 제어하거나 기능을 추가할 수 있는 패턴.
  • 초기화지연, 접근 제어, 로깅, 캐싱등 다양하게 사용 가능함.
  • 프록시 패턴을 사용할 때, 크게 인터페이스를 이용한 방식상속을 이용한 방식 2가지가 있다.
    • 인터페이스를 이용한 방식의 장점은 유연한 개발이 가능하다. ( 활용도가 높아짐 )

 

 

Proxy 패턴의 실 사용 예시

1. JDK Dynamic Proxy

  • 런타임 시점에 인터페이스를 구현하는 클래스 또는 인스턴스를 만드는 기술을 의미한다.
  • 그러나 Dynamic Proxy의 경우 인터페이스를 통해야만 구현이 가능하다.

단점

  • 인터페이스를 직접 구현해야한다.
  • 인터페이스의 모든 구현체를 구현(override)해야 한다. (특정 메서드만 프록시 사용 불가)
  • 프록시 클래스 내에 중복이 발생 할 수 있다. (메서드 마다 하는일이 비슷할 시 중복 발생 가능)

 

2. CGLib (Code Generator Library)

  • 클래스 상속을 통하여 Proxy를 동적으로 구현해 주므로 인터페이스를 사용하지 않고 Proxy를 사용할 수 있게 해준다.
  • Spring AOP, Hibernate 등에서 CGLib를 사용한다.

단점

  • 그러나, 상속을 이용한 Proxy이므로 상속이 불가(final, private 생성자, abstract)한 클래스의 경우에는 사용이 불가하다.

 

Spring AOP의 proxy 구현방식에는 2가지 종류가 있는데,

하나는 JDK Proxy(JDK Dynamic Proxy)

다른 하나는 CGLib이다. 

 

이 부분에 대해서는 더 자세히 다음 게시물에서 설명하겠다.

 

 

[참고]

https://hyunsoori.com/entry/Service-%EC%97%90%EC%84%9C-%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4-%EC%82%AC%EC%9A%A9

 

Spring 에서 Service 인터페이스 사용?

Spring 에서 Service 클래스를 만들때 인터페이스를 사용 한다? 안한다? public interface MyService { void doSomething(); } @Service public class MyServiceImpl implements MyService { @Override public void doSomething() { System.out.println

hyunsoori.com

https://jinn-blog.tistory.com/129

 

12. 프록시 패턴

1. 프록시 패턴 특정 객체에 대한 접근을 제어하거나 기능을 추가할 수 있는 패턴. 초기화지연, 접근 제어, 로깅, 캐싱등 다양하게 사용 가능함. 2. 패턴 적용 전 코드 아래와 같이 게임을 시작하

jinn-blog.tistory.com