본문 바로가기
서버/스프링

스프링을 배우기 전에(3) - 의존성 주입(Dependency Injection)

by 나이아카 2021. 3. 17.

 스프링을 배우기 전 준비해야 하는 단어입니다. DI라고도 하는 의존성 주입인데요. 이미 객체지향 프로그래밍을 하는 동안에 배웠던 단어일 수도 있습니다. 하지만 그만큼 필요한 개념이라고도 볼 수 있겠네요.

 

 DI(Dependecy Injection)는 코드에서 필요한 객체를 직접 사용하는 것이 아니라 파라미터나 세터등을 통해 외부에서 필요한 객체를 받아와서 사용하는 개념입니다.

 

class PlayList () {
    val weAre = WeAre()
    val redSun = RedSun()
}

class WeAre : Music() { ...//생략 }
class RedSun : Music() { ...//생략 }

 

 이러한 클래스가 있습니다. PlayList 클래스 내부에 존재하는 WeAre와 RedSun은 전부 Music 클래스를 extends 하고 있습니다. 이렇게 클래스를 생성할 때 마다 내부에서 따로 생성해서 class를 사용하게 됐을때 만약 WeAre 클래스에 변화가 생길 경우 모든 클래스에 직접 변경을 줘야 하는데, 의존성을 주입한 경우에는 그럴 필요가 없다고 설명하고 있습니다.

 

 스프링에서는 의존성 주입을 위해 대체적으로 사용하는 3가지 방식이 있습니다.

 

 첫 번째로는 생성자(constructor)를 통해 주입하는 방식입니다.

 두 번째로는 세터(setter) 메소드를 사용해서 주입하는 방식입니다.

 마지막은 필드 주입인데요. 이 방식은 클래스 내부 변수에 @Autowired 애노테이션을 통해 스프링에게 의존성 주입을 요청하는 것입니다.

 

 스프링이 아닌 곳에서는 크게 생성자 및 세터로 분류될 수 있겠네요.

 

class PlayList (val weAre : Music, val redSun : Music) {
    
    fun setOneMusic(val playMusic: Music) {
        weAre = playMusic
    }
    
    fun setTwoMusic(val playMusic : Music) {
        redSun = playMusic
    }
}

class WeAre : Music() { ...//생략 }
class RedSun : Music() { ...//생략 }

 

 세터와 생성자를 통해 의존성을 주입하는 형태의 코드입니다. 이 경우 전부 상속중인 Music을 이용해 파라미터로 받아오고 있습니다. 이는 상속받고 있는 WeAre 클래스나 RedSun 클래스가 다른 클래스로 변동되어도 이상 없이 사용할 수 있도록 해 줍니다.(저처럼 코딩에 대해 한참 배우고 있는 사람이라면 아마 명확하게 이해가 되지 않으실 수도 있습니다. 이는 추가적인 스프링 학습을 통해 더 올바른 방향으로 이 방법을 사용할 수 있습니다.)

 

 이렇게 코드 내부에 직접 선언하는 것이 아니라 세터나 생성자를 통해 필요한 코드를 외부에서 받아올 수 있다면 직접 선언하는 것 보다 더 많은 이점을 가져올 수 있습니다.

 

  • 두 클래스 간의 결합도를 낮출 수 있습니다.
  • 코드의 재활용성을 상승 시켜 줍니다.
  • 활용에 따라서 더 유연하고 덜 의존적인 코드를 제작할 수 있습니다.

 물론 이 장점들은 어떤 방식으로 코딩을 하느냐에 따라 다르게 나타날 수 있습니다. 의존성 주입을 하더라도 하지 않은 코드처럼 직접 특수성을 띄는 코드를 만들어낸다면 의존성 주입의 효과는 거의 나타나지 않을 것입니다. 하지만 모든 코드의 설계가 그렇듯, 조금 더 깊게 생각해서 설계하면 이후에 더 쉽게 사용할 수 있습니다.

댓글