ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • Spring - Autowired를 쓰면 좋지 않은 이유
    프레임워크/Spring 2020. 12. 28. 20:04

    AutoWired

    스프링을 쓸 때 Bean을 만들어서 주입을 하여 Singleton으로 많이 사용하고들 한다. 필드인젝션은 간단하게 @Autowired로 변수에 표시만 해주면 주입이 완료된다. 그런데 Intellij를 쓰면 노란 줄이 뜨면서 경고가 나오는데.. 경고를 무시해도 잘 작동이 되기 때문에 무시하고 계속 사용해오곤 했다. 그러나,, 찐 개발자가 되기 위해서는 이러한 내부적인 이유도 알아야 한다고 생각이되어 오늘은 그 이유를 파헤쳐보도록하자.

     

    먼저 @Autowired이 분이 하시는 역할에 대해서 알아보자. 이분은 개발자들이 개발하기 편하게 하기 위한 역할을 해주시는 분인데, 저는 나이가 어려 경험해보지 못했지만 spring 초기 버전에는 xml파일에 명세를 적어줘야 했다.  대충 아래와 같은 코드들을 클래스를 하나 만들 때마다 적어줘야했다고 생각하면 될 것 같다.

    <bean id="asd" class="com.adf.cc"/>
    

     

    조금 더 버전이 발전했을 때는 xml파일은 아니고 ApplicationConfig에 java코드로 Annotation을 사용하여 해결할 수 있게 되었다. 자바코드로 설정할 수 있다는 것만 다르지 설정을 해줬어야했다는 것이다. 그런데 @Autowired의 등장으로 위와 같이 명세를 적어줘야하는 일을 하지 않아도 되게 된 것이다. 이것이 @Autowired의 역할이다. 연관되어 있는 객체의 Bean을 자동으로 연결시켜주는 것이다.

    Dependency Injection

    Autowired이든지 Constructor를 쓰던지 결국 목적은 DI를 하기 위해서인데, 스프링에서만 쓰이는 용어가 아니라 Front-end 프레임워크, 아이폰, 안드로이드를 비롯한 모든 영역에서 사용되는 개념이다. 한 번 알아놓으면 또 까먹겠지만 또 알아놓으면 좋을 것 같다.

     

    객체지향에서 피해야할 것은 지나치게 큰 의존도를 만드는 것이다. 각각의 객체지향 프로그래밍을 하는 것은 여러가지 이유가 있겠지만 유지 보수, 개발할 때 용이함도 매우 큰 몫이다. 지금 같이 하드웨어가 좋은 세상에는 사실상 가장 중요한 이유가 아닐까라는 생각을 한다.

     

    이런 경험이 있을 것이다. 하나의 로직을 만들고 그 로직을 계속해서 ctrl + c, ctrl + v로 셀 수 없이 많은 곳에 사용했다가, 그 로직이 잘못되어 추후에 확장할 때에 문제가 생기는 경험 말이다. 이 때 그 로직은 다 고쳐야할 뿐만 아니라 관련되어 있는 곳들도 하나하나 다 고쳐줘야 한다. 이것이 쉽게 말해 의존성이다. 이런 상황을 피하면서 리팩토링하기 위해 우리는 의존성이 커지는 것을 피해야한다.

     

    주입 방법

    스프링에서 의존성을 주입하는 방법은 크게 3가지가 있을 것이다.

     

    1. 가장 편리한 @Autowired를 사용하는 것

    @Autowired
    private MyClass myClass;

    2. Setter를 사용하는 것

    private MyClass myClass;
    
    @Autowired
    public void setMyClass(MyClass myClass) {
    	this.myClass = myClass;
    }

    3. Constructor를 사용하는 것 - Constructor는 @Autowired를 생략해도된다.

    private MyClass myClass;
    
    public cClass(MyClass myClass) {
    	this.myClass = myClass;
    }
    

     

    위 셋 중에서 스프링이 우리에게 경고를 내며 쓰라고 권하는 것은 3번이다. 그 이유에 대해 알아보자. 이렇게 권하는 이유는 반드시 문제가 생길 수 있기 때문에 이렇게 권하는데 그 가능성은 두가지가 있다.

     

    @정확하지 않은 정보

    첫번째는 setter를 사용했을 때이다. Setter를 사용하면 set을 안해주면 그 객체는 Null으로 정의가 되어있지 않게 된다. 근데 cClass에서 myClass를 set을 해주지 않고 사용하게 된다면 NullPointException이 나면서 500에러를 내려줄 것이다.

     

    두번째는 Autowired를 썼을 때인데, Autowired를 사용하면 순환참조가 되는 케이스가 있을 때 빌드과정에서는 알 수 없다는 점입니다. 해당 코드가 실행되기 전까지는 남극의 빙산이됩니다. 그러나 Constructor를 사용하면 bean이 생성될 때 순환참조를 하고 있는 것을 알아채고 빌드가 되지 않게 됩니다. 고로 추후에 생길 문제를 사전에 방지할 수 있게 됩니다.

     

    생성자로 주입했을 때의 장점 

    생성자로 주입했을 때의 장점은 여러가지가 있는데, 대부분은 개발할 때의 이점이 많은 것 같다.

     

    1. 주입 받는 대상을 immutable하게 선언할 수 있다.

    2.  생성자의 파라미터를 통해 의존관계를 한 눈에 파악할 수 있다.

    3. NPE을 방지할 수 있다.

    4. 리팩토링이 필요함을 알려준다.

    5. 단일 책임 원칙을 위반함도 알려준다. 

     

    결론 - 더 좋은 코드 품질을 위해서 사용해야 한다.

    댓글

Designed by Tistory.