Spring의 주요 기능을 말하면 빠지지 않는 것이 의존성주입
이다. 그렇다면 이 의존성 주입이라는 것이 정확하게 무엇을 가리키고 어떤 방식으로 이루어지기에 그렇게 강조되는 것인지 알아보자.
의존성 주입이란 외부에서 두 객체 간의 관계를 결정해주는 디자인 패턴으로, 인터페이스를 사이에 둬서 클래스 레벨에서는 의존 관계가 고정되지 않도록하고 런타임시에 관계를 동적으로 주입하여 유연성을 확보하고 결합도를 낮추는 기법
을 이야기한다.
이렇게 읽어서는 이해하기가 쉽지 않다…
먼저 의존성
에 대해서 알아보자
의존성이란 한 객체가 다른 객체를 사용할때 의존성이 있다라고 이야기한다.
public class School{
private Student student;
}
라고 했을때 School은 Student클래스에 의존성이 있다, 의존하고있다라고 이야기할 수 있는 것이다. 이때, School에서 Student 클래스를 직접 생성하는 것이 아니라 외부에서 Student 인스턴스를 생성해서 주입해준다는 점에 주목하여야한다.
이 상황에서 의존성을 주입하는 방식은 크게 3가지로 나뉜다.
차례대로 알아보도록 하자.
간단하게 정리하자면 생성자를 통해 의존관계를 주입하는 방법이다.
public class Student{
private String name;
private int std_num;
@Autowired // 생성자가 1개일 경우 생략 가능
public Student(name, std_num){
this.name = name;
this.std_num = std_num;
}
}
생성자 주입은 생성자의 호출 시점에 1회 호출되는 것이 보장된다. 이때 주입받은 객체는 변경이 불가하기에 불변의 객체를 만들고자할때 사용될 수 있다. Spring에서는 생성자 주입을 지원해주기때문에 생성자가 1개 뿐일 경우, @Autowired를 생략해도 주입이 가능하도록 해준다.
setter를 통해서 의존성 주입
⇒ 빈 생성자, 또는 빈 정적 팩토리 메서드가 필요( final 필드 생성 불가, 의존성 불변 보장 불가)
⇒ 런타임 도중 의존성 변경 필요가 있을때 setter 주입 사용
⇒ 의존성 불변을 보장하고싶다면? 생성자 주입 추천!
public class A{
private B b;
@Autowired
public void setB(B b){
this.b = b;
}
}
@Autowired 어노테이션을 필드에 직접 적용해서 사용
But, 생성자, setter도 없는 상황에서 test와 같은 상황에서 의도적으로 의존성을 주입시킬수가 없어 spring 자체적으로도 warning 메시지를 띄움.
⇒ 사용 자제!
public class A{
@Autowired
private B b;
...
}
되도록이면 생성자 주입을 사용하자!