스프링은 IoC 컨테이너로 빈을 관리한다.
스프링은 DI를 사용한다....??? 스프링 공부하면서 많이 들어왔던 내용이지만 어물쩡 넘어갔지만 이번 시간에 확실히 정리해보겟다!
IoC는 Inversion of Contro의 약자로 글자 그대로 읽어보면 제어의 역전이라는 뜻이다. 한국말이 맞나 싶긴한데 조금 쉽게 봐 보겠다.
우선 우리는 객체가 필요할 때 객체가 필요한 곳에 직접 객체를 생성하곤 했다.
public class A{
b= new B();
}
위의 예제를 보면 우리는 class A안에 B객체를 사용하기 위해 new 키워드로 클래스B의 객체 생성을 직접하였다.
🙊 IoC
객체의 생성 및 관리 책임을 개발자가 아닌 컨테이너(예: 스프링 컨테이너)가 맡는 것을 의미한다. 코드로 보면 훨씬 이해가 쉬우니 코드로 따라가보겠다.
//스프링 컨테이너가 객체를 관리하는 예
public class A{
private B b;
}
다음 코드에서 보면 클래스B 객체를 직접 생성하지 않는다. 즉 외부 어디선가에서 (= 스프링 컨테이너) 받아오고 있고 이를 객체b에 할당 중이라고 볼 수 있다. 이처럼 제어의 역전을 적용하게 된다면 객체는 자신이 사용하는 의존 객체를 직접 생성하거나 관리하지 않고, 스프링 컨테이너가 필요할 때 주입해준다.
🙈 DI
객체들을 관리하기 위해 제어의 역전을 사용했다면 제어의 역전을 구현하기 위해 사용하는 방법이 DI이다. (DI는 IoC의 구현 방법 중 하나!)
DI는 Dependency Injection의 약자로 의존성 주입을 의미한다.
우선 Dependency 의존적이다 라는 말부터 살펴보겠다.
// classA
class A{
private B b = new B();
/*
생략
*/
}
//class B
class B
{//생략
}
프로그래밍에서 의존적이다라는 것을 알아보자면, 예를 들어 B 내부 변경이 일어나게 되면 A에도 영향을 미치게 된다.만약 B에 final 필드가 추가된다면 클래스A에서 new B()부분은 컴파일 에러가 나게 된다.
즉 위 코드에서 클래스A가 클래스B를 사용하기 때문에 A는 B에 의존적이다라고 말한다.
Injection은 주입이라는 뜻이다. 더 쉬운 말론는 넣어준다고 보면 되겠다.
즉, DI는 의존성이 있는 코드 개체를 넣어 준다라는 뜻이다.
A라는 클래스가 B클래스에서 의존하고 있는 상황에서 A클래스에서 B클래스를 직정 생성해서 사용하는 것이 아니라 외부에서 B클래스의 인스턴스를 생성해서 주입해 주었다는 것이다.
코드로 확인해보자!
public class UserService {
private UserRepository userRepository;
public UserService() {
this.userRepository = new UserRepository(); // 직접 생성
}
// ...
}
다음 코드를 본다면 UserService'는 직접적으로 'UserRepository'를 생성하고 의존하고 있다. 이로 인해서 'UserService'와 'UserRepository' 간에 강한 결합이 형성되고 이런 경우 유지 보수성이 떨어지며, 코드 변경 시 여러 클래
스에 영향을 줄 수 있다.
DI를 사용한 경우
@Component
public class Coffee {
private final Latte latte;
public Coffe(Latte latte) {
this.latte = latte;
}
}
@Component
public class Snack {
private Jelly jelly;
@Autowired
public void setJelly(Jelly jelly) {
this.jelly=jelly;
}
}
@Component
public class ExampleService {
@Autowired
private Dependency dependency;
}
위에서 사용되는 @Autowired라는 어너테이션은 스프링 컨테이너에 있는 빈이라는 것을 주입하는 역할을 란다. 이때 빈은 쉽게 말해 스프링 컨테이너에서 관리하는 객체를 말한다.
정리하자면...
이러한 개념들이 스프링 프레임워크에서 중요한 이유는,어플리케이션의 결합도를 낮추고, 유연성 및 확장성을 높이는 데 기여해 애플리케이션 개발자가 비즈니스 로직에 집중할 수 있도록한다.
+) @Component 방법과 @Configuration 방법 추가 예정