의존은 변경에 따른 영향이 전파되는 관계를 의미하며 이를 처리하는 방식에 의존 주입이 있다. 이번 포스트에서는 스프링에서 의존 주입이 어떤 방식으로 일어나는지 알아보자. 또한 생성자 또는 설정 메서드를 이용해 의존 객체를 주입하는 방법을 예제 코드를 통해 확인해보자.
스프링의 의존 주입(DI: Dependency Injection)
스프링
스프링은 DI를 지원하는 조립기이다. 따라서 다음과 같은 특징을 갖는다.
- 필요한 객체를 생성한다.
- 생성한 객체에 의존을 주입한다.
- 객체를 제공하는 기능을 정의한다.
스프링을 이용한 객체 조립과 사용
이전 글에서 소개한 Assembler(조립기) 대신 스프링을 사용해보자. 스프링을 사용하려면 스프링이 어떤 객체를 생성하고 의존을 어떻게 주입할지를 설정하는 설정 클래스를 먼저 정의해야 한다. 아래는 설정 클래스의 예시 코드다.
@Configuration
public class AppCtx {
@Bean
public ExDao exDao(){
return new ExDao();
}
@Bean
public ExService exService(){
// exDao()가 생성한 객체를 주입
return new ExService(exDao());
}
}
- @Configuration 애노테이션은 스프링 설정 클래스를 의미한다. 이 애노테이션을 붙여야 스프링 설정 클래스로 사용할 수 있다.
- @Bean 애노테이션은 해당 메서드가 생성한 객체를 스프링 빈이라고 설정하는 것이다. 각 메서드마다 한 개의 빈 객체를 생성하며, 메서드 이름을 빈 객체의 이름으로 사용한다.
설정 클래스를 만들었으면 이 설정 클래스를 이용해서 컨테이너를 생성해야 한다. AnnotaionConfigApplicationContext 클래스를 이용해서 스프링 컨테이너를 생성할 수 있다. 컨테이너를 생성한 후 getBean() 메서드를 이용해서 사용할 객체를 가져올 수 있다. 아래는 앞서 작성한 AppCtx 클래스를 이용해 스프링 컨테이너를 생성하고 이름이 "exService"인 빈 객체를 가져오는 코드이다.
// 설정 클래스를 이용해서 스프링 컨테이너를 생성
ApplicationContext ctx = new AnnotationConfigApplicationContext(AppCtx.class);
// getBean() 메서드를 이용하여 사용할 객체를 구함
ExService exService = ctx.getBean("exService", ExService.class);
스프링에서의 DI 방식
스프링에서 의존 객체를 주입하는 방법은 생성자 방식과 setter 메서드 방식이 있다. 두 방식은 각각 장단점이 있으며 맞고 틀린 것은 없으니 상황에 따라 적합한 방식을 사용하면 된다.
생성자 방식
생성자를 통해서 의존 객체를 주입받아서 필드에 할당하는 방식이다. 이 방식을 사용하면 빈 객체를 생성하는 시점에 모든 의존 객체가 주입된다. 아래 코드는 생성자를 이용해 ExDao 객체를 전달받는 ExService 클래스의 예시다.
public class ExService {
private ExDao exDao;
public ExService(ExDao exDao) {
this.exDao = exDao;
}
}
생성자에 전달할 의존 객체가 여러 개인 경우에도 마찬가지로 주입하면 된다. 아래는 ExDao와 SampleDao 두 개의 파라미터를 전달받는 클래스 SampleService이다.
public class SampleService {
private ExDao exDao;
private SampleDao sampleDao;
public SampleService(ExDao exDao, SampleDao sampleDao) {
this.exDao = exDao;
this.sampleDao = sampleDao;
}
}
설정 클래스에서는 생성자를 이용해 의존 객체를 주입하기 위해 해당 설정을 담은 메서드를 호출한다.
@Configuration
public class AppCtx {
@Bean
public ExDao exDao(){
return new ExDao();
}
@Bean
public SampleDao sampleDao(){
return new SampleDao();
}
@Bean
public ExService exService(){
// exDao()가 생성한 객체를 주입
return new ExService(exDao());
}
@Bean
public SampleService sampleService(){
// exDao()와 sampleDao()가 생성한 객체를 주입
return new SampleService(exDao(), sampleDao());
}
}
setter 메서드 방식
생성자로 객체를 주입하는 것 외에 setter 메서드를 이용해서 객체를 주입받기도 한다. 이 방식은 setter 메서드의 이름을 통해 어떤 의존 객체가 주입되는지 알 수 있다는 장점이 있다. 아래는 앞서 작성한 ExService 클래스를 setter 메서드 방식으로 변경한 코드이다. 두 개의 세터 메서드는 각 객체에 대한 의존을 주입할 때 사용한다.
public class SampleService {
private ExDao exDao;
private SampleDao sampleDao;
public void setExDao(ExDao exDao) {
this.exDao = exDao;
}
public void setSampleDao(SampleDao sampleDao) {
this.sampleDao = sampleDao;
}
}
아래는 setter 메서드를 이용해 의존을 주입하는 설정 코드를 AppCtx에 반영한 코드이다.
@Configuration
public class AppCtx {
@Bean
public ExDao exDao(){
return new ExDao();
}
@Bean
public SampleDao sampleDao(){
return new SampleDao();
}
@Bean
public ExService exService(){
// exDao()가 생성한 객체를 주입
return new ExService(exDao());
}
@Bean
public SampleService sampleService(){
// setter를 이용하여 exDao 빈, sampleDao 빈 주입
SampleService sampleService = new SampleService();
sampleService.setExDao(exDao());
sampleService.setSampleDao(sampleDao());
return sampleService;
}
}
참고 서적: <초보 웹 개발자를 위한 스프링 5 프로그래밍 입문>
이 포스팅은 쿠팡 파트너스 활동의 일환으로, 이에 따른 일정액의 수수료를 제공받습니다.
'Java > [스프링 5 프로그래밍 입문]' 카테고리의 다른 글
[Spring] 의존 자동 주입(1) - @Autowired 애노테이션 (0) | 2021.07.30 |
---|---|
[Spring] 스프링 애노테이션을 사용한 의존 주입(DI) (0) | 2021.07.28 |
Dependency, DI, Assembler (의존, 의존 주입, 주입기) 개념 정리 (0) | 2021.07.22 |
[Spring] 스프링 컨테이너(Container) 의미 (0) | 2021.07.22 |
[Spring] 스프링 프로젝트 시작하기 (Maven) (0) | 2021.07.21 |
댓글