[스프링] 스태틱 메서드가 아닌 스프링 싱글톤 빈을 사용해야하는 이유
스프링의 application context에 관리되는 빈들은 기본적으로 싱글톤으로 관리된다.
상태를 갖지 않는 객체의 메서드를 사용하기 위하여 매번 인스턴스화 하는 것은 효율적이지 않다.
스프링에서는 이러한 이유로 싱글톤 타입이라는 것을 지원하고 싱글톤 타입으로 스프링 빈을 관리할 땐, 속성 없이 메서드만 구현하여 사용을 한다.
허나, 이렇게 메서드만 사용할 목적이라면 굳이 인스턴스화할 필요도 없고 static으로 만들어서 사용해도 되지 않나라는 의문이 들수 있다.
static 메서드를 사용하는 것과 싱글톤 빈의 메서드를 사용하는 것의 차이는 클래스 메서드이냐, 인스턴스 메서드이냐의 차이이다.
즉, 인스턴스를 사용하냐 하지 않냐의 차이이고, 이는 객체지향적인 프로그래밍을 할 수 있냐 없냐로 나타난다.
static으로 사용하면 상속을 통한 다형성을 사용하지 못한다. 캡슐화도 제한적이다.(메서드 구현부가 노출됨)
따라서 이 글에서는 스프링에서 제공해주는 객체지향적인 장점을 사용할 수 있는 기능에 대해 알아보겠다.
DI (with DIP)
스프링의 DI는 의존객체 생성, 주입을 프레임워크에서 대신해준다.
DIP를 활용하여 추상화에 의존하는 의존관계를 설정하면 의존관계 변경시에도 코드를 통한 변경이 아닌 어노테이션이나
xml 설정 변경을 통해 대응할 수 있다.
허나 static 메서드를 사용하는 경우 클래스에 의존하게 되므로 클래스간의 강한 결합이 발생하고 의존관계에 변경사항이 생겼을때에도 코드 변경이 불가피 하다.
* DI를 사용하는 이유 : 객체 생성과 의존관계 설정에 대한 책임을 프레임워크에 넘길 수 있음(개발자가 하지 않아도 됨)
* DI에 DIP를 적용하는 이유 : 의존관계 변경에 유연한 구조를 갖추기 위해(결합도를 낮출 수 있음)
스프링 aop
스프링 aop는 프록시를 통해 구현된다.
프록시는 타깃 객체를 래핑하여 타깃 객체로의 접근을 제어하고 부가기능을 제공해준다.
프록시는 타깃 객체의 상위타입을 똑같이 상속받고 있기에 다른 객체가 타깃의 상위 타입으로 호출하면
프록시가 요청을 가로채는 방식으로 동작한다.
static 메서드를 호출한다는 것은 클래스를 통해 직접 호출한다는 것이기에 타깃과 같은 상위 타입을 상속하여 요청을 가로채는 프록시 방식을 사용할 수 없다.
따라서 static 메서드를 호출하는 방식으로는 스프링의 aop를 활용할 수 없다.