[Spring 실전] 정답 공개! 비즈니스 로직부터 DB 연결까지 직접 구현하기

시에나·2026년 1월 11일

스프링 기초

목록 보기
13/13

지난 시간에 드린 미션, 성공하셨나요?
"데이터베이스에서 데이터를 가져와 최댓값을 찾는 서비스 만들기"였죠.

오늘은 그 솔루션을 함께 코딩해보면서, 스프링이 실제 애플리케이션에서 어떻게 동작하는지 눈으로 확인해 보겠습니다.


1. 설계도 그리기 (DataService 인터페이스)

가장 먼저 할 일은 데이터 접근 계층(Data Layer)의 규칙을 만드는 것입니다. 나중에 DB가 바뀌어도 유연하게 대처하기 위해 인터페이스를 사용합니다.

package com.in28minutes.learnspringframework.examples.c1;

public interface DataService {
    int[] retrieveData();
}

2. 구현체 만들기 (MongoDB & MySQL)

인터페이스를 구현한 두 개의 클래스를 만듭니다. 이때 중요한 점은 클래스 위에 @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 };
    }
}

3. 비즈니스 로직 만들기 (의존성 주입)

이제 핵심 로직을 담당하는 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() 같은 코드를 전혀 쓰지 않았습니다. 생성자에 파라미터로 적어주기만 하면 스프링이 알아서 연결해 줍니다.


4. 실행 및 결과 확인

이제 메인 애플리케이션(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

결과 분석

  1. 스프링이 BusinessCalculationService를 만들려고 보니 DataService가 필요합니다.
  2. 후보가 Mongo와 MySQL 두 개네요.
  3. Mongo에 @Primary가 붙어있는 걸 보고, MongoDbDataService를 선택해서 주입합니다.
  4. Mongo의 데이터 {11, 22, 33, 44, 55} 중 최댓값인 55가 출력됩니다.

이번 예제가 중요한 이유

우리는 "어떻게 객체를 만들고 연결할지" 고민하지 않았습니다. 오직 "어떤 로직을 짤지(findMax)"에만 집중했습니다.

  • 객체 생성? → 스프링이 함 (@Component)
  • 객체 연결? → 스프링이 함 (생성자 주입)
  • 우선순위 결정? → 스프링이 함 (@Primary)

이것이 바로 스프링 프레임워크를 사용하는 진짜 이유입니다. 개발자는 복잡한 설정이나 배관 공사(Wiring)에서 벗어나, 핵심 비즈니스 로직에만 집중할 수 있게 됩니다.

0개의 댓글