전 포스팅에서 POJO에 대해 알아보았다.
이때 3가지 특징을 소개했는데 오늘 알아볼 Ioc/DI/AOP가 이 특징들과 관련이 있다.
우선 특정 규약에 종속되지 않는 특징과 관련된 성질들에 대해 알아보자.
여러분이 알고있는 그 의존이 맞다.
public class A {
private B b;
public A(){
this.b = B.getInstance();
}
위 코드에서 만약 멤버변수인 B의 객체를 B2클래스의 인스턴스로 바꾸게 된다면 코드를 수정해야 한다.
즉, B클래스는 독자적으로 활동이 가능하지만 A클래스는 B클래스 없인 정상적인 작동이 어렵다.
A클래스가 처한 상황을 'A는 B에 의존한다'라고 한다.
의존성에 대해 알아봤다. 그럼 의존성 주입은 무엇일까?
위 예시에서 B 객체를 B2클래스의 인스턴스로 바꾸는건 매우 간단한 작업이다.
하지만 수 백, 수 천줄의 코드가 작성된 페이지에서 코드를 바꾸기란 쉽지 않다.
그래서 DI가 등장했다.
DI는 이처럼 의존적인 객체를 생성하거나 제어하지 않고 외부에서 필요한 객체를 주입하는 방식이다.
객체 자체가 아니라 Constructor(생성자) 또는 Setter 같은 Framework를 사용하여 의존하는 대상에게 의존성을 주입한다.
보통 의존성 주입 어노테이션은 @Autowired, @Resource, @Inject 세 가지가 있는데
@Autowired만 Spring 환경에 적합하기에 @Autowired의 3가지 방식만 다뤄볼 예정이다.
public class A {
@Autowired
private B b;
}
말 그대로 필드에 @Autowired를 선언하여 의존성을 주입하는 방식이다.
매우 간단하지만 외부에서 변경이 불가능하다는 단점이 있다.
public class A {
private B b;
@Autowired
public void setB(B b){
this.b = b;
}
}
수정자 set을 통해 의존성을 주입하는 방법이다.
public class A {
private final B b;
@Autowired
public A(B b){
this.b = b;
}
}
생성자에 @Autowired를 선언하여 의존성을 주입한다.
Final 선언을 통한 null 방지, 순환 참조를 방지하는 등 다른 두 방식 대비 이점이 커서 사용이 권장되는 방식이다.
Ioc - Inversion of Control, 제어의 역전.
역전이라... 뭔가 주종 관계가 바뀐것 처럼 들린다. 어느정도는 맞다.
기존에는 개발자가 모든 흐름을 제어했으나, 그 제어를 Framework가 한다는 의미이다.
위에서 @Autowired 어노테이션을 선언하면 Framework가 알아서 두 객체에 의존성을 주입한다.
그로인해 개발자는 의존성에 신경을 덜 쓰고 오로지 로직에만 집중할 수 있게 된다.
이 그림은 Framework에 해당하는 Container가 각 객체에 알아서 의존성을 주입하는 흐름을 보여준다.
Ioc, 매력적인 녀석이다.
참고