Spring 에서 Service 클래스를 만들때 인터페이스를 사용 한다? 안한다?

 

public interface MyService {
    void doSomething();
}


@Service
public class MyServiceImpl implements MyService {
    @Override
    public void doSomething() {
        System.out.println("hello Im Impl Service");
    }
}

 

보통 스프링 개발할때 서비스를 위와 같은 패턴으로 사용은 하지만, 늘 그래왔듯이 사용하는 개발자가 적지 않다라는 것을 알았다.

그래서 궁금해서 블라인드에 투표를 올려봤다. (꽤 많은 분들이 투표를 해줬다ㅎㅎ)

 

Spring 에서 Service 인터페이스

 

203명의 개발자분들이 투표를 해주셨고, 사용한다라는 개발자가 근소한 차이로 15명이 많았다. 사실 비슷하다라고 보면 될것 같다

근데 댓글을 달아주신 것들을 보면, 예전부터 서비스에 인터페이스를 습관적으로 사용하게 되서 관성에 의해 사용하는 개발자분들이 간혹 있는 것 같다.

 

그렇다면 왜 예전부터 서비스에 인터페이스를 습관적으로 사용하였을까?

예전에는 Spring 에서 AOP Proxy 를 만드는 방식이 JDK Dynamic Proxy 를 사용하여 인터페이스 기반으로만 만들게 되어 있었다.

예를 들어, 인터페이스가 있어야지 @Transactional 이런 어노테이션이 동작이 가능하기 때문이다. (AOP Proxy 만들어서 트랜잭션을 처리하기 때문에)

특정 버전부터 CGLIB 라이브러리를 사용하여, 클래스 기반으로 AOP Proxy 를 만들도록 지원을 하게 되었다.

그래서 개발자는 AOP Proxy를 만드는 방식을 선택을 할 수 있게 되었다.

 

SpringBoot 에서는 디폴트로 클래스 기반으로 만들도록 아래와 같이 설정되어 있다.

 

  • true : CGLIB를 사용하여, 클래스를 상속받아 AOP Proxy를 만듬
  • false : JDK Dynamic Proxy를 사용하여 인터페이스를 데코레이션 해서 AOP Proxy를 만듬
spring.aop.proxy-target-class=true

 

결론적으로 인터페이스 사용하는 이유는?

OOP 관점에서 봤을때 인터페이스는 다형성(Polymorphism) 혹은 개방 폐쇄 원칙 때문에 사용한다. 보통 흔히 얘기하는 느슨한 결합 혹은 유연해지도록 하기 위해 사용한다고 봐야 한다.

 

그렇다면 Spring 에서 Service 는 다형성이 필요할까?

제 경험적으로 봤을때 다형성이 필요 없는 경우가 대부분이였던 것 같다. 사실 Service 보다 다른 클래스에서 다형성이 필요했던것 같다. 그리고 대부분의 Spring 프로젝트에서 Service 가 하나의 인터페이스에 하나의 구현체로 있는 것이 대부분이였다.

 

그래서 요즘은 나도 Service 에 인터페이스가 불필요 하면 사용하지 않고 있다. 다형성이 필요한 곳에만 인터페이스 사용한다.

다만 proxy-target-class=false 로 설정하면 어플리케이션이 동작하지 않는다는 찜찜함은 감수해야 한다.

 

 

 

 

 

 

 

 

 

 

 

반응형
댓글