항상 물심양면 지원해주신 멘토님, 깊은 인사이트와 학습 기회를 주셔서 진심으로 감사합니다.
스프링을 처음 접했을 때는 단순히 “자바 웹 프레임워크”라는 정도의 인식만 가지고 있었다.
하지만 김영한님의 스프링 핵심 원리 - 기본편 강의를 완강하고 나니, 단순히 기술을 사용하는 것을 넘어
스프링의 철학과 아키텍처, 그리고 객체 지향 설계 원칙까지 깊이 이해하게 되었다.
어떤 내용을 공부했는가?
1. 스프링의 탄생과 철학
- 스프링이 왜 등장하게 되었는지, 그리고 기존 EJB의 문제점을 어떻게 개선했는지부터 시작했다.
- 스프링은 단순히 프레임워크가 아니라, 객체지향 프로그래밍을 실현하기 위한 도구라는 본질을 알게 됐다.
2. 스프링 컨테이너와 DI (의존관계 주입)
- ApplicationContext의 개념부터 빈 등록 방식, 자동 주입 방식 (@Autowired, 생성자 주입 등)까지 상세하게 다뤘다.
- 특히 의존성 주입이 왜 객체 지향적인 설계와 테스트에 유리한지를 깨달았고, 필드 주입의 문제점도 명확히 인식하게 되었다.
3. 스프링 빈의 생명주기와 스코프
- 빈의 생성 시점부터 소멸까지의 흐름과 @PostConstruct, @PreDestroy 같은 생명주기 콜백을 활용한 관리 기법을 배웠다.
- singleton, prototype, request, session 스코프의 차이를 이해하고 실제 웹 환경에서 어떻게 동작하는지 정리했다.
4. 인터페이스 중심의 설계와 역할 분리
- OrderService와 DiscountPolicy의 예제를 통해, 인터페이스와 구현 분리를 통해 확장성과 테스트 용이성을 확보하는 방법을 학습했다.
- 다양한 전략 패턴 적용 사례를 통해 OCP 원칙(Open-Closed Principle)을 실무 코드에 적용하는 법을 익혔다.
5. 싱글톤 패턴과 스프링의 빈 관리
- 순수 자바 환경에서 직접 싱글톤 패턴을 구현해보고, 스프링 컨테이너가 이를 어떻게 관리해주는지를 비교했다.
- 상태를 가지는 싱글톤 빈의 위험성과, 무상태(stateless) 설계의 중요성도 체감할 수 있었다.
6. 프록시와 의존성 순환 문제 해결
- @Lazy로 순환 참조를 지연시키거나, 프록시 패턴을 이용해 DI 구조를 개선하는 기법까지 익혔다.
- 스프링이 어떻게 내부적으로 문제를 해결하고, 개발자는 어떻게 대응해야 하는지를 알게 되었다.
7. AppConfig와 DI 설계 패턴 적용
- AppConfig 클래스를 통해 역할과 구현의 분리, 설정과 사용의 분리를 실제 코드로 연습했다.
- 스프링 없이도 DI를 적용할 수 있는 순수 자바 기반 구성 방법을 통해, DI 설계의 본질을 경험할 수 있었다.
8. @Configuration과 @Bean의 원리
- @Configuration이 붙은 설정 클래스에서 @Bean 메서드를 사용하는 것이 단순한 메서드 호출이 아닌,
- CGLIB 바이트코드 조작을 통한 싱글톤 보장 기법이라는 점을 학습했다.
- 스프링이 내부적으로 어떻게 빈을 한 번만 생성해서 공유하는지의 원리를 직접 확인할 수 있었다.
9. 컴포넌트 스캔과 자동 등록
- @Component, @Controller, @Service, @Repository 등 컴포넌트 계열 애노테이션을 통한 빈 자동 등록 기능을 학습했다.
- @ComponentScan, basePackages, excludeFilters 옵션을 통해 빈 스캔 범위를 지정하거나 제외하는 방식도 실습했다.
10. @Autowired를 활용한 의존성 주입 심화
- 생성자, 필드, 세터 방식 각각의 특징을 정리하고, 스프링이 생성자가 하나만 있으면 자동으로 주입하는 동작을 확인했다.
- @Qualifier, @Primary, @Value, @RequiredArgsConstructor를 통해 동일 타입 빈 충돌 문제 해결법도 함께 정리했다.
11. 테스트 코드 작성으로 스프링 기능 검증
- @SpringBootTest 없이 순수 자바 환경에서 AppConfig를 이용한 테스트 작성 방법 학습
- 의존성 주입, 빈 싱글톤 여부, 정책 교체 시 동작 확인 등 실무에 가까운 테스트 코드를 함께 구성했다.
가장 크게 얻은 것
1. “왜 이렇게 설계해야 하는가?”를 끊임없이 고민하는 습관
단순히 코드를 작성하는 게 아니라,
역할과 책임, 의존성과 확장성, 테스트 가능성을 중심에 두고 코드를 바라보는 눈이 생겼다.
2. 객체지향적인 코드와 스프링의 구조가 맞닿아 있음을 체감
강의를 들으며 가장 놀라웠던 점은, 스프링이 단순히 기술 집합이 아니라
객체지향 설계 철학을 구현한 구조라는 점이었다.
OCP, DIP, SRP 같은 원칙들이 어떻게 실무 코드에 녹아드는지를 배웠고,
앞으로의 개발 방식이 달라질 거란 확신이 들었다.
3. 기록하면서 이해가 깊어진 경험
단순히 듣고 끝낸 것이 아니라, 각 개념을 내 언어로 풀어 쓰며 정리한 덕분에
단기간에 스프링 기본기를 탄탄히 다질 수 있었다.
티스토리 기술블로그를 통해 복습도 되고, 나중에 실무 중 막힐 때마다 찾아보는 좋은 레퍼런스가 생겼다.
마치며
스프링은 단순히 문법을 익히는 것이 아니라, 좋은 코드와 좋은 설계를 고민하는 여정이었다.
강의를 통해 익힌 내용을 직접 기록하고, 블로그로 정리하며
그저 “아는 수준”을 넘어 “설명할 수 있는 수준”으로 끌어올릴 수 있었다.
이 시리즈를 통해 스프링의 본질을 조금 더 가깝게 느꼈고,
실무에서도 더욱 견고한 백엔드 시스템을 설계할 자신감을 얻게 되었다.
'Spring' 카테고리의 다른 글
[Spring 완전 정복 시리즈 - MVC편] 2편 - 서블릿의 기본 개념과 동작 원리 (4) | 2025.08.07 |
---|---|
[Spring 완전 정복 시리즈 - MVC편] 1편 - 웹 애플리케이션의 이해 (7) | 2025.08.02 |
[Spring 완전 정복 시리즈] 23편 - 빈 스코프 완전 정복 (3): Provider vs 프록시, 그리고 정리 (1) | 2025.08.01 |
[Spring 완전 정복 시리즈] 22편 - 빈 스코프 완전 정복 (2): 웹 스코프와 Provider/프록시 패턴 (0) | 2025.08.01 |
[Spring 완전 정복 시리즈] 21편 - 빈 스코프 완전 정복 (1): 싱글톤과 프로토타입 (0) | 2025.08.01 |