오랜만에 TIL을 작성해본다!
사실 우리나라는 자바 공화국이라고 부를 정도로, Java를 많이 사용한다. 정확히는 Java라는 언어만 사용하기 보다는 Java와 함께 Spring 프래임워크를 함께 서버 구축하는데 사용을 한다. 서버 구축을 위한 프래임워크는 생각보다 다양하다. Javascript의 Node.js, Python의 Django, C#의 .Net 등등.. 그런데 우리나라 만큼은 아니더라도.. 해외에서도 Spring은 서버에서 주로 사용하는 프래임워크다.
왜 Spring을 선호하는 걸까? Spring 만의 장점이 있는 걸까? 지금 이번 글에서 다뤄보고자 한다.
보편적으로 사용하는 백엔드 프래임워크 비교해보자
| 언어 | Java | Javascript | Python | PHP | C# |
| 프래임워크 | Spring | Node.js | Django | PHP | .Net |
| 주요 특징 | - 대규모 enterprise - 보안성&확장성 - 방대한 생태계 |
- 빠른 비동기처리 - 프론트와 동일언어 |
- 빠른 개발 속도 - 직관적인 ORM |
- 빠른 구축 - 웹 호스팅 용이 |
- Windows에 친화 - 안정적인 성능 |
다음과 같이 표로 정리가 가능하다. 그럼 표에 있는 내용을 하나하나 자세히 알아보자.
1. 방대한 생태계
Spring의 생태계는 매우 방대하다. 아래 그림과 같이 다양한 기술을 라이브러리를 통해 사용이 가능하기 때문이다. 데이터베이스와 소통을 하고 싶다? 그럼 spring-data-jpa를 사용하면 된다. 데이터베이스가 NoSQL이다? 그럼 spring-data-mongodb와 같이 다른 것을 사용하면 된다. 데이터를 캐싱하고 싶다? 그럼 spring-data-redis를 사용하면 된다.

데이터베이스이 접근을 하는 데에도 이렇게 맞춤형 라이브러리 혹은 의존성이 있으니, 개발자 입장에서는 더할 나위가 없다! 그 외에도 Spring Cloud, Spring Web등 다양한 기능이 있으며, 무엇보다 모듈화가 되어있어 결합도가 낮은 편, 따라서, 필요할 때만 추가해 사용이 가능하다. 따라서 확장성에도 매우 용이하다.
2. 높은 보안성
Spring의 방대한 생태계에는 spring-security가 있다. 라이브러리 의존성을 쉽게 추가할 수 있다는 용이함 뿐만 아니라, 강력한 필터 체인/인가 처리 기능도 있기 때문이다.
사용자가 HTTP 요청 → Dispatcher-Servlet(요청을 매핑된 컨트롤러에 배차해주는 서블릿)으로 가기 전에, Security Filter Chain에서 이를 가로채서 검사를 한다. 즉, 모든 요청을 필터 체인에서 감시를 하여 더욱 안전하다는 것! 필터로는 BasicAuthenticationFilter와 같은 기본부터, JwtAuthenticationFilter와 같이 Jwt 토큰을 확인하는 것 까지 다양하다.
만약 Filter에서 인증이 성공하면 SecurityContextHolder라는 곳에서 인증된 객체를 저장하여 사용에 편리하다. 이 뿐만 아니라, 우리가 자주 사용하는 소셜 로그인, 그러니까, 카카오 계정 로그인, 네이버 계정 로그인 등도 OAuth2LoginAuthenticationFilter로 통해 편리하게 필터링이 가능하다.
[클라이언트] → [필터 체인]
│
┌─────────┴─────────┐
[JwtAuthenticationFilter] [OAuth2LoginAuthenticationFilter]
│ │
[AuthenticationManager] [OAuth2UserService]
│ │
[SecurityContextHolder] [SecurityContextHolder]
│ │
[인가처리] [인가처리]
│ │
[컨트롤러] [컨트롤러]
3. 강력한 트랜잭션 관리
먼저 트랜잭션(Transaction)에 대해 간단히 설명하자면, 데이터베이스의 상태를 변화시키기 위해 수행하는 하나의 작업의 단위이다. 다만, 여기서 중요한 점은, 하나의 작업 단위라 해서, 일이 하나만 일어나는 것이 아니라는 것이다.
예를 들어 "연아"가 "율희"에게 1만원을 송금했다고 치자. 그렇다면 "연아"의 계좌에 10,000만원을 빼는 -10,000만 하면 되는 것인가? 절대 그렇지 않다. 먼저 연아의 계좌에서 10,000원을 뺀 다음, 율희의 계좌에 10,000원을 더하는 두 개의 상태를 변화시키는 Update작업을 해야 한다.
대규모 시스템에서는 이러한 하나의 작업에 무수히 많은 DB 내에서 일이 발생하게 된다. 만약 중간에 하나라도 실패를 한다면? 그러니까, 율희의 계좌에 만원을 추가하였지만, 연아의 계좌에 만원을 빼는 작업을 하지 못했다면? 그렇다면 이를 처음부터 되돌리는 rollback작업을 해야 한다.
Spring에서는 @Transactional이라는 어노테이션을 선언하는 것 만으로, 트랜잭션 시작, 커밋, 롤백을 자동으로 처리할 수 있는 편의 기능을 제공한다.
@Transactional
public void registerOrder() {
송금자_계좌에서_인출();
수취자_계좌에게_입금();
}
그 이외에도, 전파 옵션(Propagation)이라는 기능도 제공하는데, 트랜잭션 안에 또 다른 트랜잭션을 호출할 때, 이를 어떻게 처리해야 할 지 선택할 수 있는 옵션을 제공한다. 몇 가지 자주 사용하는 옵션을 예를 들자면:
- Propagation.REQUIRED: 트랜젝션 A 내부에 트랜젝션 B 가 실행될 경우, A와 B는 같은 트랜잭션에 묶이게 된다.
- Propagation.REQUIRES_NEW: 트랜젝션 A 내부에 트랜젝션 B 가 실행될 경우, A 트랜젝션은 중단되고, B에서 새 트랜잭션이 시작된다.
- Propagation.MANDATORY: 트랜젝션 A 내부의 트랜젝션 B는 A가 실행 될 때만 가능하도록 묶어 놓은다.
이외에도 Rollback 설정 기능 등 대규모 엔터프라이즈에 적합한 다양한 기능과 오랜 사용으로 충분히 검증되었기 때문에 Spring을 주로 사용하는 것이라고 요약하고 싶다!
'TIL' 카테고리의 다른 글
| 동시성 문제: 여러 개의 스레드를 돌리면 반드시 발생하는 일 (8) | 2025.08.08 |
|---|---|
| OAuth란? 그리고 적용시 고려해야 하는 점 (20) | 2025.07.29 |
| 백엔드 개발자라면 당신이 알아야 할 것! OSI 7 계층 (0) | 2025.02.18 |
| 기술면접 대비: 백엔드 신입에게 자주 물어보는 질문들 (4) | 2025.02.06 |
| Base 64 인코딩(encoding)이란 무엇인가? - 사용하는 이유 (0) | 2025.01.14 |