Post

[Spring] 1. Spring

백엔드 개발자로 취업하려면 Java 와 Spring 기술은 필수라는 말이 있다.
국내에서는 가장 많이 쓰이는 웹 프레임워크이며 전자정부 표준프레임워크이기도 하다.
Spring이 인기 있는 이유는 무엇일까? 왜 Spring 기술을 공부해야할까?
하나씩 차근차근 정리해보자.


스프링(Spring)이란?


  • 자바 언어 기반의 애플리케이션 프레임워크.
  • Spring Boot, Spring Data, Spring Security 등 스프링 생태계 전체를 의미하기도 한다.


스프링의 등장

스프링이 등장하기 전, 순수한 자바 코드로 기능을 구현하던 시절에는 개발자가 모든 부품을 직접 구현하고 조립했어야 했다.

아래 코드는 순수 자바 코드다. 저장소에서 데이터를 가져와 모두 출력하는 간단한 코드로 예시를 살펴보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class SampleController {
    // Controller가 Service 부품을 직접 생성한다.
    private SampleService service = new SampleService(); 

    public void show() {
        // ...
        service.getList();
        // ...
    }
}

class SampleService {
    // Service가 Repository 부품을 직접 생성한다.
    private SampleRepository repository = new SampleRepository();

    public void getList() {
        // ...
        repository.findAll();
        // ...
    }
}


위 코드를 보면 ControllerService 를 만들고 ServiceRepository 를 만들고 있다.
코드가 동작하는데에는 아무런 문제가 없지만 SampleRepositoryRealRepository 로 바뀐다고 하면 Service 코드를 수정해야 한다. 심지어는 Controller 코드도 수정해야 할 수도 있다.

위와 같이 서로 의존성이 높은 코드는 부품 하나만 바뀌었는데 전체를 뜯어고쳐야하는 비효율적인 구조라고 볼 수 있다.
Spring 은 객체를 만들고 관리하는 일을 자동으로 처리하면서 위 문제를 해결해준다.



스프링의 핵심 철학 - IoC & DI

  1. IoC (Inversion of Control, 제어의 역전)

    객체 생성·의존성 주입은 스프링 이 담당하고, 개발자는 구현 로직에 집중한다.”

    • 개발자가 직접 new 키워드를 사용해 객체를 만들지 않아도 된다.
    • 스프링 내부에 있는 스프링 컨테이너 가 필요한 객체(Bean) 을 생성하고, 관리하고, 소멸시키는 모든 과정을 책임진다.

  2. DI (Dependency Injection, 의존성 주입)

    생성자 / 세터 / 필드 등을 통해 필요한 의존 객체를 스프링 컨테이너로부터 주입받는다.”


이전의 구현했던 순수 자바 코드를 스프링 방식으로 바꿔보자.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
@Controller
public class SampleController {
    // Controller는 Service가 필요하다고 '선언'만 한다. (final 키워드 주목)
    private final SampleService service;

    // 생성자를 통해 외부(스프링 컨테이너)에서 Service 객체를 '주입' 받는다.
    public SampleController(SampleService service) {
        this.service = service;
    }

    public void show() {
        // ...
        service.getList(); // 주입받은 객체의 메서드 호출
        // ...
    }
}

@Service
public class SampleService {
    // Service 도 마찬가지로 Repository 를 선언만 하고, 생성자를 통해 주입 받는다. 
    private final SampleRepository repository;

    public SampleService(SampleRepository repository) {
        this.repository = repository;
    }

    public void getList() {
        // ...
        repository.findAll();
        // ...
    }
}


이제 더 이상 클래스 내부에서 new 키워드로 객체를 직접 생성하지 않는다.
@Controller , @Service 와 같은 애너테이션만 붙여주면 스프링 컨테이너가 알아서 해당 객체를 찾아 주입해 준다.


생성자 주입이 중요한 이유
DI에는 필드 주입, 수정자(Setter) 주입, 생성자 주입 세 가지 방식이 있다.
이 중 생성자 주입을 사용하는 것이 좋다.
객체가 생성되는 시점에 모든 의존성이 주입되어 불변성을 보장할 수 있고, 테스트 코드 작성에도 유리하다.




공부자료
그림으로 배우는 스프링 6
인프런 - 김영한 스프링 로드맵

This post is licensed under CC BY 4.0 by the author.