지난 시간에 드린 미션, 성공하셨나요?
"데이터베이스에서 데이터를 가져와 최댓값을 찾는 서비스 만들기"였죠.
오늘은 그 솔루션을 함께 코딩해보면서, 스프링이 실제 애플리케이션에서 어떻게 동작하는지 눈으로 확인해 보겠습니다.
가장 먼저 할 일은 데이터 접근 계층(Data Layer)의 규칙을 만드는 것입니다. 나중에 DB가 바뀌어도 유연하게 대처하기 위해 인터페이스를 사용합니다.
package com.in28minutes.learnspringframework.examples.c1;
public interface DataService {
int[] retrieveData();
}
인터페이스를 구현한 두 개의 클래스를 만듭니다. 이때 중요한 점은 클래스 위에 @Component를 붙여서 스프링에게 "이거 네가 관리해!"라고 알려주는 것입니다.
그리고 미션 조건에 따라 MongoDB에 @Primary를 붙여서 우선권을 줍니다.
① MongoDB 서비스 (우선순위 1등)
@Component
@Primary // <-- 핵심! 둘 중 얘가 선택됩니다.
public class MongoDbDataService implements DataService {
@Override
public int[] retrieveData() {
return new int[] { 11, 22, 33, 44, 55 }; // 최댓값 55
}
}
② MySQL 서비스
@Component
public class MySqlDataService implements DataService {
@Override
public int[] retrieveData() {
return new int[] { 1, 2, 3, 4, 5 };
}
}
이제 핵심 로직을 담당하는 BusinessCalculationService를 만듭니다. 여기서 중요한 건 생성자 주입을 통해 DataService를 받아오는 것입니다.
@Component
public class BusinessCalculationService {
private DataService dataService;
// 생성자 주입: 스프링이 알아서 DataService(여기선 Mongo)를 넣어줍니다.
public BusinessCalculationService(DataService dataService) {
super();
this.dataService = dataService;
}
public int findMax() {
// 1. 데이터 가져오기 (retrieveData)
// 2. 스트림을 이용해 최댓값 찾기
return Arrays.stream(dataService.retrieveData())
.max().orElse(0);
}
}
우리는 new MongoDbDataService() 같은 코드를 전혀 쓰지 않았습니다. 생성자에 파라미터로 적어주기만 하면 스프링이 알아서 연결해 줍니다.
이제 메인 애플리케이션(RealWorldSpringContextLauncherApplication)에서 실행해 봅시다.
@Configuration
@ComponentScan
public class RealWorldSpringContextLauncherApplication {
public static void main(String[] args) {
// 1. 스프링 컨텍스트 실행
try (var context = new AnnotationConfigApplicationContext(
RealWorldSpringContextLauncherApplication.class)) {
// 2. 비즈니스 서비스 빈(Bean) 가져오기
var service = context.getBean(BusinessCalculationService.class);
// 3. 최댓값 출력
System.out.println(service.findMax());
}
}
}
실행 결과:
55
BusinessCalculationService를 만들려고 보니 DataService가 필요합니다.Mongo와 MySQL 두 개네요.Mongo에 @Primary가 붙어있는 걸 보고, MongoDbDataService를 선택해서 주입합니다.Mongo의 데이터 {11, 22, 33, 44, 55} 중 최댓값인 55가 출력됩니다.우리는 "어떻게 객체를 만들고 연결할지" 고민하지 않았습니다. 오직 "어떤 로직을 짤지(findMax)"에만 집중했습니다.
@Component)@Primary)이것이 바로 스프링 프레임워크를 사용하는 진짜 이유입니다. 개발자는 복잡한 설정이나 배관 공사(Wiring)에서 벗어나, 핵심 비즈니스 로직에만 집중할 수 있게 됩니다.