"Spring"이라 했을 때 많이 나오는 키워드 중 하나는 바로 DI, 즉 의존성 주입이다.
도대체 이게 왜 Spring의 키워드일까? 그 이유는 바로 Spring이 이 DI 과정을 알아서 해 주기 때문이다.
최근에 Spring 공부를 다시 시작하게 되었는데 아주 간단하게 DI에 대해 알아보자!
먼저, DI란 뭘까?
DI (Dependency Injection): 의존성 주입
고객 관리 서비스를 개발할 때 고객을 관리하는 Service Class가 있으면 고객의 데이터를 다루는 Dao Class가 있을 것이다. 이 경우 아래와 같이 두 Class간의 의존성이 생기게 된다.
class MemberService {
private MemberDao memberDao = new MemberDao();
}
MemberService memberService = new MemberService();
위와 같이 직접 생성하는 방식은 꽤 쉽다! 하지만 이 방법은 유지보수 관점에서 아래와 같은 어려움이 있을 수 있다.
- MemberDao를 상속받는 CachedMemberDao를 사용하려면 각 코드를 모두 변경해 주어야 한다.
위 코드는 아래와 같이 외부에서 의존성을 주입하는 방식으로 변경할 수 있다. 이렇게 변경할 경우 CachedMemberDao를 사용하더라도 Service Class를 사용하는 곳에서만 변경하면 되며 앞서 의존 객체를 직접 생성했던 방식에 비해 변경할 코드가 한 곳으로 집중되는 것을 알 수 있다.
- 주입 방식으로는 1) 생성자 주입 방식, 2) Setter 주입 방식이 있다.
class MemberService {
private MemberDao memberDao;
MemberService(MemberDao memberDao) {
this.memberDao = memberDao;
}
}
MemberService memberService = new MemberService(new CachedMemberDao());
이러한 객체들을 Spring에서는 Bean이라 부르며 사용자가 특정 객체를 Bean으로 등록하면 이후 이 객체에 대한 생성 및 소멸에 대한 과정을 Spring Bean Container에서 대신 처리한다. 이 현상을 IoC(Inversion of Control: 제어의 역전)이라고 한다. 말 그대로 객체의 제어를 개발자가 아닌 Spring이 맡았다는 의미이다. (처음엔 이 단어가 너무 낯설고 이해가 안됐다 ㅠ)
아주 간단한 코드로 사용 방식을 살펴보자!
// @Configuration: 스프링 설정 클래스를 의미한다.
@Configuration
class AppCtx {
// @Bean: Bean으로 등록할 객체를 의미한다.
// Spring은 @Bean이 붙은 메서드에 대해 하나의 객체만 생성. 객체가 사용될 때 마다 생성 X.
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
@Bean
public MemberService memberService() {
return new MemberService(memberDao());
}
}
class Main {
private static ApplicationContext ctx = null;
// AnnotationConfigApplicationContext 를 사용해서 스프링 컨테이너를 생성한다.
public static void main(String[] args) {
ctx = new AnnotationConfigApplicationContext(AppCtx.class);
// 설정 파일(AppCtx 클래스)로부터 생성할 객체와 의존 주입 대상을 정한다.
MemberService memberService = ctx.getBean("memberServce", MemberService.class);
}
}
두 개의 config를 사용할 경우엔 어떻게 사용할까? 아래 코드로 간단하게 알아보자. 이 때 사용된 @AutoWired는 Spring Bean에 의존하는 다른 Bean을 자동으로 주입하고자 할 경우 사용된다.
@Configuration
class AppCtx1 {
@Bean
public MemberDao memberDao() {
return new MemberDao();
}
}
@Configuration
class AppCtx2 {
@AutoWired
MemberDao memberDao;
}
class Main {
private static ApplicatonContext ctx = null;
public void main(String args[]) {
ctx = new AnnotationConfigApplicationContext(AppCtx1.class, AppCtx2.class);
}
}
이렇게 Spring DI에 대해 알아보았다. 물론, 주입할 객체를 모두 Bean으로 등록할 필요는 없지만 보통은 등록해서 사용한다.
Spring과 좀 친해진 생각이 들었길 바라며! :)
출처
'공부이야기 > Spring' 카테고리의 다른 글
[Spring] Bean Scope의 종류 (0) | 2021.05.13 |
---|---|
[Spring] IoC 컨테이너란? (IoC: Inversion of Control) (0) | 2021.05.02 |
[Spring] Dependency Injection(DI) - 의존성 주입 (0) | 2021.05.02 |
댓글