본문 바로가기
Backend/Spring

Spring 개요

by Jiyoung Oh 2025. 3. 28.

 


프레임워크(Framework)
는 애플리케이션 개발 시 공통적으로 사용되는 구조와 기능들을 미리 제공하여, 개발자가 비즈니스 로직에 집중할 수 있도록 도와주는 뼈대 혹은 틀입니다.

<프레임워크의 장점>

  • 반복적인 코드 최소화
  • 일관된 아키텍처 제공
  • 생산성 향상
  • 코드의 재사용성과 유지보수 용이성

Spring은 자바 생태계에서 가장 많이 쓰이는 대표적인 프레임워크로, 웹, 데이터베이스, 보안, 테스트 등 전 영역을 포괄합니다. 이번 글에서는 이런 Spring의 전반적인 개념에 대해 정리해보고자 합니다.


Spring 프레임워크

Java 기반의 엔터프라이즈급 어플리케이션을 만들기 위한 오픈소스 프레임워크로, 객체 지향 프로그래밍(OOP)을 더 잘 활용할 수 있도록 돕습니다. 복잡한 웹 애플리케이션의 개발을 단순화시키는 것이 목적이며, 모듈화된 구조로 필요한 기능만 선택적으로 사용할 수 있습니다.

Spring의 핵심 목표는 개발자가 비즈니스 로직에 집중할 수 있도록 인프라 관련 작업을 처리해주는 것이며, POJO(Plain Old Java Object) 기반의 개발을 권장합니다.

POJO(Plain Old Java Object)

  • 특별한 규약(예: 특정 상속, 어노테이션, XML 설정 등)에 따르지 않는 순수한 자바 객체
  • getter/setter, 생성자, toString() 등 기본 기능만 가진 클래스

스프링은 이러한 POJO 객체들을 스프링 컨테이너에서 관리하여 개발자가 프레임워크에 종속되지 않고 자유롭게 개발할 수 있도록 합니다.

Spring 모듈 구조

Spring 프레임워크는 다양한 기능을 각각의 모듈(Module)로 분리해 제공합니다. 모듈이란 특정 기능을 담당하는 독립적인 단위이며, 필요한 기능만 선택적으로 사용할 수 있도록 구성되어 있습니다.

아래와 같은 모듈 구조 덕분에 스프링은 유연하고 확장 가능한 애플리케이션 개발이 가능합니다.

분류 주요 모듈 설명
Core Container Core, Beans, Context, Expression Language IoC/DI 기반 핵심 기능 (의존성 주입, Bean 관리 등)
AOP AOP 로깅, 보안, 트랜잭션과 같은 공통 관심사 분리
Data Access JDBC, ORM, Transactions 데이터베이스 접근 및 트랜잭션 처리 지원
Web Web, Web MVC 웹 애플리케이션 및 REST API 개발
Test Test 단위/통합 테스트 지원 (Mock, 컨텍스트 로딩 등)

Spring 용어 정리

  • Bean: 스프링 컨테이너가 생성하고 관리하는 객체
  • ApplicationContext: 전체 애플리케이션을 구성하는 스프링 컨테이너 (Bean 관리, 설정, AOP 등 포함)
  • IoC Container: 객체의 생성과 관리를 담당하는 컨테이너 → ApplicationContext가 대표적
  • Component Scan: 특정 패키지를 탐색하여 자동으로 Bean으로 등록하는 기능 (@Component, @Service, @Repository 등)
  • Auto Configuration: 스프링 부트에서 사용하는 자동 Bean 설정 기능

Spring 제공 기능

  • 의존성 주입(DI)
  • AOP(관점 지향 프로그래밍)
  • 트랜잭션 관리
  • MVC 웹 프레임워크
  • JDBC, ORM 지원 등 데이터 접근 기능

Spring 장점

  • 생산성 ↑: DI, AOP, 어노테이션 설정 등으로 코드 간결
  • 유지보수 ↑: 관심사 분리, 모듈화, 계층 분리
  • 테스트 용이: 의존성 주입 구조로 Mock 객체 사용 용이

Bean과 ApplicationContext

ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
OrderService orderService = context.getBean(OrderService.class);

Bean

스프링 컨테이너가 생성하고 관리하는 자바 객체입니다. 일반적으로 개발자가 작성한 클래스에 @Component, @Service, @Repository 등의 어노테이션을 붙여 등록합니다.

 

Bean 생명주기 단계

      1. 등록: @Component, @Bean
      2. 의존성 주입: @Autowired
      3. 초기화: @PostConstruct
      4. 소멸: @PreDestroy

ApplicationContext

      • Bean을 생성하고 관리하는 스프링의 핵심 컨테이너

스프링 컨테이너의 핵심 인터페이스로, Bean 등록/생성/조회 등을 담당합니다.

ApplicationContext는 BeanFactory의 상위 개념으로, 아래와 같은 부가 기능도 제공합니다.

      • 국제화 메시지 처리
      • 이벤트 전파
      • AOP 연동 지원
      • Bean 생명주기 인터페이스 지원

Spring MVC 아키텍처

      • Spring MVC는 Model-View-Controller 패턴을 따르는 웹 프레임워크
      • 3계층 아키텍처: Controller → Service → Repository
      • @Controller는 요청을 받고, @Service는 로직 처리, @Repository는 DB와 통신
      • 역할 분리로 유지보수, 테스트 용이
      • 단일 책임 원칙에 맞춘 구조
      • Spring MVC는 REST API 작성도 자연스럽게 지원하며, @RestController, @ResponseBody, @RequestBody 등을 사용

<3계층 아키텍처>

      • Controller: 클라이언트 요청을 받고 응답 처리 (프레젠테이션 계층)
      • Service: 비즈니스 로직 처리 (비즈니스 계층)
      • Repository: 데이터베이스 접근 처리 (영속성 계층)

Spring MVC는 흔히 3계층 아키텍처라고 불리는 구조를 따릅니다. 위와 같은 구조는 역할을 분리해서 유지보수성과 테스트를 좋게 만듭니다. 이것이 바로 단일 책임 원칙(SRP)에 부합합니다.

 

<핵심 컴포넌트>

Spring MVC에서 핵심 컴포넌트는 프레임워크가 내부적으로 사용하는 주요 구성 요소들을 말합니다. 각 컴포넌트는 MVC 흐름의 한 단계에 관여합니다.

컴포넌트 역할
DispatcherServlet 프론트 컨트롤러. 모든 요청의 진입점으로 요청을 받아 다른 컴포넌트로 위임
HandlerMapping 어떤 컨트롤러가 요청을 처리할지 매핑 정보 탐색
Controller 실제 요청을 처리하고, 결과(Model과 View)를 반환
ViewResolver 컨트롤러가 반환한 View 이름을 기반으로 실제 View 객체 결정
View 최종적으로 클라이언트에게 응답을 보여주는 HTML, JSON 등 렌더링 담당

 

<요청 처리 흐름>

      1. 클라이언트가 요청을 보냄
      2. DispatcherServlet이 요청을 받음
      3. HandlerMapping이 적절한 Controller 탐색
      4. Controller에서 Service, Repository를 호출해 비즈니스 처리
      5. Controller가 Model + View 이름을 반환
      6. ViewResolver가 실제 View 파일(.jsp, .html 등)을 결정
      7. View를 렌더링해서 클라이언트에 응답

Spring MVC의 전체 요청-응답 흐름

    • 클라이언트 요청이 DispatcherServlet에 도착
    • DispatcherServlet은 핸들러 매핑을 통해 적절한 컨트롤러를 찾고 실행
    • 컨트롤러는 서비스, 레포지토리를 거쳐 DB와 통신한 후 모델 데이터를 반환
    • ViewResolver가 알맞은 View를 선택하고, 렌더링된 결과가 사용자에게 전달

Spring의 주요 특징

    1. IoC(제어의 역전)와 DI(의존성 주입)
      객체 생성 및 의존성 주입을 개발자가 아닌 스프링 컨테이너가 담당하는 철학으로, 유연성과 테스트 용이성을 높입니다.
      • IoC(제어의 역전)
        • 객체 간의 결합도를 낮추고 모듈성을 높이는 핵심 메커니즘
        • 객체 생성과 관리를 Spring IoC 컨테이너가 자동으로 처리
        • XML, Java Config, Annotation 기반 설정 지원
        • 장점: 코드의 재사용성 증가, 테스트 용이성 향상, 느슨한 결합 달성
      • DI(의존성 주입)
        • 객체의 생명주기 관리를 개발자가 아닌 Spring 컨테이너가 담당
        • 객체 생성, 초기화, 소멸 과정을 프레임워크가 제어
        • 개발자는 비즈니스 로직에 집중 가능
    2. AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)
      로깅, 트랜잭션 관리 등 공통 기능을 분리하여 핵심 로직을 깔끔하게 유지할 수 있도록 합니다.
      • 횡단 관심사(로깅, 보안, 트랜잭션 등)를 모듈화
      • 핵심 비즈니스 로직과 부가 기능의 분리
      • 프록시 기반의 AOP 지원
      • 코드 중복 최소화 및 모듈성 향상
    3. 어노테이션 기반 설정과 컴포넌트 스캔
      • XML 기반 설정의 복잡성과 번거로움을 해결
      • 코드와 설정의 결합도를 높이고 가독성 향상
      • 개발자의 설정 부담을 획기적으로 감소
    4. 강력한 MVC 아키텍처
      • 웹 애플리케이션 개발을 위한 구조화된 아키텍처 제공
      • DispatcherServlet을 통한 중앙집중식 요청 처리
      • 컨트롤러, 서비스, 레포지토리 계층의 명확한 분리
    5. ORM 통합
      • Hibernate, JPA 등 다양한 ORM 프레임워크와의 seamless 통합
      • JdbcTemplate을 통한 간편한 데이터베이스 작업
      • 컨트롤러, 서비스, 리포지토리 계층의 명확한 분리
    6. 테스트 지원
      • 단위 테스트와 통합 테스트를 위한 포괄적인 지원
      • @Test, @MockBean 등의 어노테이션을 통한 쉬운 테스트 작성
      • Spring Boot Test 모듈로 더욱 간편해진 테스트 환경
    7. 보안 프레임워크
      • Spring Security를 통한 강력한 인증 및 권한 부여 메커니즘
      • OAuth, JWT 등 다양한 인증 방식 지원
      • 보안 설정의 유연성과 확장성
    8. 마이크로서비스 아키텍처 지원
      • Spring Cloud를 통한 분산 시스템 개발 지원
      • 서비스 디스커버리, 로드밸런싱, 서킷브레이커 등 기능 제공
      • 클라우드 네이티브 애플리케이션 개발에 최적화

 

1. IoC(제어의 역전)와 DI(의존성 주입)

IoC (Inversion of Control)

  • 객체 제어권을 개발자가 아닌 스프링이 관리
  • DI, AOP는 IoC 구현 방법

IoC는 제어 흐름의 주도권을 개발자 코드가 아닌 프레임워크(스프링 컨테이너)가 가지는 개념입니다. 이를 통해 객체 간 결합도를 줄이고 유연한 구조를 구성할 수 있습니다. 또한 객체의 생성, 의존성 주입, 생명주기 관리 등을 컨테이너가 담당함으로써 애플리케이션의 유연성과 테스트 용이성을 높입니다.

DI (Dependency Injection)

  • 의존성을 외부에서 주입
  • DI는 IoC를 구현하는 가장 대표적인 방법

DI는 IoC를 구현하는 가장 대표적인 방법입니다. 객체가 자신의 의존성을 내부에서 생성하는 대신, 외부(스프링 컨테이너) 에서 주입받아 사용하도록 합니다.

 

<DI의 장점>

  • 결합도 감소 (유지보수성과 확장성 향상)
  • 테스트 용이성 (Mock 객체 주입 가능)
  • 객체 간 명확한 역할 분리 및 의존성 관리

생성자 주입 예시

@Component
public class OrderService {
  private final PaymentService paymentService;

  @Autowired
  public OrderService(PaymentService paymentService) {
    this.paymentService = paymentService;
  }
}

 

세터 주입 예시

@Component
public class OrderService {
  private PaymentService paymentService;

  @Autowired
  public void setPaymentService(PaymentService paymentService) {
    this.paymentService = paymentService;
  }
}

 

2. AOP (Aspect-Oriented Programming, 관점 지향 프로그래밍)

  • 로깅, 트랜잭션, 보안처럼 공통 기능을 핵심 로직과 분리하여 모듈화하는 방식
  • 핵심 로직과 분리하여 유지보수 ↑
  • 핵심 어노테이션: @Aspect , @Before, @After, @Around

AOP는 핵심 비즈니스 로직 외에 공통적으로 반복되는 부가 로직(로깅, 보안, 트랜잭션 등)을 분리하여 재사용성과 유지보수성을 향상시키는 프로그래밍 방식입니다.

 

<AOP의 주요 용어>

  • Aspect: 공통 기능 모듈 (e.g. LoggingAspect)
  • Join Point: 실행 지점 (e.g. 메서드 호출)
  • Advice: 실행될 코드 (e.g. @Before, @After)
  • Pointcut: Advice가 실행될 조건 지정
  • Weaving: Advice를 실제 코드에 적용하는 과정
@Aspect
@Component
public class LoggingAspect {
  @Before("execution(* com.example.service.*.*(..))")
  public void logBefore(JoinPoint joinPoint) {
    System.out.println("Method called: " + joinPoint.getSignature().getName());
  }
}

3. 어노테이션 기반 설정과 컴포넌트 스캔

어노테이션

<bean id="orderService" class="com.example.OrderService"/>

스프링에서는 위와 같이 원래 XML 파일로 Bean 설정을 했습니다.

하지만 XML이 많아지면 복잡해지기 때문에, 요즘은 아래와 같 Java 코드에서 어노테이션을 활용한 설정을 선호합니다.

@Component
public class OrderService {}

Spring 주요 어노테이션 정리

어노테이션 설명
@Component 일반적인 컴포넌트 클래스 (기본형)
@Service 비즈니스 로직 계층에서 사용
@Repository DAO 계층, 예외 변환 지원
@Controller 웹 요청을 처리하는 MVC 컨트롤러
@RestController @Controller + @ResponseBody, REST API용 컨트롤러
@Autowired 스프링이 자동으로 의존성 주입
@PostConstruct, @PreDestroy 객체 초기화 및 소멸 시점에 실행되는 콜백 메서드 지정

컴포넌트(Component)

@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {}

스프링에서 컴포넌트는 스프링 컨테이너가 관리하는 객체(Bean)를 말합니다. 일반적으로 @Component 또는 그 하위 어노테이션(@Service, @Repository, @Controller)이 붙은 클래스는 컴포넌트로 간주되며, 자동으로 스프링 컨테이너에 등록됩니다.

  • 컴포넌트는 객체를 개발자가 직접 생성하지 않고, 스프링이 생성하여 관리 (IoC 개념 기반)
  • 자동 등록을 위해 @ComponentScan 어노테이션을 사용하며, 지정한 패키지 이하에서 해당 어노테이션이 붙은 클래스를 찾아 Bean으로 등록
  • @ComponentScan 으로 자동으로 빈을 등록할 수 있음
  • 어노테이션을 통한 빈 자동 감지
    • @Component, @Service, @Repository, @Controller, @RestController
    • 특정 계층별 역할에 따라 명시적 표현 가능

Spring Boot의 등장과 목적

Spring Boot는 Spring의 철학과 기능을 유지하면서, 개발자가 빠르게 시작하고 운영할 수 있도록 돕는 프레임워크입니다.

기존 Spring 프레임워크는 설정(xml, 자바 기반 설정 등)이 많고 복잡하여 진입장벽이 높았습니다.

Spring Boot는 Spring의 설정을 간소화하고, 애플리케이션 개발과 배포를 빠르게 할 수 있도록 지원합니다.

주요 특징

  • 내장 서버(Tomcat, Jetty 등) 지원 → WAR 배포 없이 JAR 실행 가능
  • 자동 설정(Auto Configuration) → 대부분의 설정을 자동화
  • 스타터 의존성 제공 → 필요한 기능을 모듈 단위로 관리
  • 운영 도구 내장 (Actuator, Metrics 등)

Spring과 Spring Boot의 차이점

항목 Spring Framework Spring Boot
설정 방식 수동 설정 (XML, JavaConfig) 자동 설정 중심
서버 구성 외부 WAS 사용 내장 WAS 제공
시작 속도 상대적으로 느림 빠르게 프로젝트 시작 가능
프로젝트 구조 자유도 높음 관례 중심 구조 제공
의존성 관리 수동 설정 Starter로 간단하게 구성

 


[참고자료]
https://docs.spring.io/spring-framework/docs/3.2.x/spring-framework-reference/html/overview.html