[Sprint 성취도 평가] Spring과 Spring Boot 이론평가
문제1. IoC와 DI의 관계에 대해 설명하고, 이들이 Spring에서 어떤 장점을 제공하는지 설명하세요.
[SB] [Spring과 Spring Boot]
문제1-1. 답변
@Service나 @Repository 같은 애너테이션이 붙여진 클래스를 IoC 컨테이너가 Bean으로 생성하고, 해당 클래스 사용 시 해당 애너테이션이 의존성을 자동으로 주입한다. 이로 인해 객체를 자동으로 생성하면서 생성자도 직접 선언할 필요가 없어진다.
- 장점
- 결합도 감소
- Bean으로 생성되어 생명주기가 동일해짐
- 테스트 쉬워짐?
문제 1-2. 정리
IoC는 Spring이 객체를 대신 만들어주고 관리하는 것을 의미하며, DI는 그렇게 만들어진 객체를 필요한 곳에 주입해주는 것을 의미합니다. 이 두 개념의 관계는 다음과 같습니다:
- Spring(IoC)이 필요한 모든 객체를 미리 만들어서 관리합니다.
- 개발자가 객체가 필요하다고 표시해두면, Spring이 해당 객체를 주입(DI)해줍니다.
이러한 방식은 다음과 같은 장점을 제공합니다:
- 개발자가 직접 객체를 생성하고 관리할 필요가 없습니다.
- 필요한 객체를 Spring이 자동으로 주입해주므로 편리합니다.
- 코드가 더 깔끔해지고 관리하기 쉬워집니다.
문제 1-3. 채점 코멘트
| ✔️ IoC와 DI의 개념을 각각 설명 | 2.5/4점 |
| ✔️ IoC와 DI의 관계 설명 | 2/3점 |
| ✔️ Spring에서 제공하는 장점 설명 | 2/3점 |
✅ 잘한 부분
- @Service, @Repository 애너테이션과 IoC 컨테이너를 연결해서 설명하고 있어요. Spring 동작 구조를 실제 코드 요소와 연결한 점이 좋습니다.
- 컨테이너가 Bean을 생성한다는 흐름을 이해하고 있어요. IoC 컨테이너의 역할을 올바르게 인식하고 있습니다.
- 의존성 자동 주입을 언급하고 있어요. DI 메커니즘의 핵심 동작을 잘 짚고 있습니다.
- 결합도 감소와 테스트 용이성을 장점으로 제시하고 있어요. 중요한 효과를 인식하고 있습니다.
❗ 아쉬운 부분
- IoC와 DI의 개념 정의가 직접적으로 설명되지 않았어요. 애너테이션 동작 설명 중심으로 서술되어 있습니다.
- “생성자도 직접 선언할 필요가 없어진다”는 표현은 부정확해요. 생성자 선언 여부와 DI는 다른 개념이며, 생성자 주입은 오히려 권장되는 방식입니다.
- “Bean으로 생성되어 생명주기가 동일해짐”이라는 장점은 의미가 모호해요. 싱글톤 스코프, 생명주기 관리 개념과 구분해서 설명되면 좋겠습니다.
- 테스트 쉬워짐? 이라는 표현에서 확신이 부족해 보여요. 이유까지 함께 설명되면 좋습니다.
📚 더 공부하면 좋은 내용
- IoC의 정확한 정의를 정리하면 좋아요. IoC는 객체 생성, 의존 관계 연결, 생명주기 관리의 제어권이 개발자가 아닌 컨테이너로 넘어가는 개념입니다. 애너테이션은 이를 돕는 설정 수단이에요.
- DI의 의미도 명확히 이해하면 좋아요. DI는 의존 객체를 직접 생성하지 않고 외부에서 주입받는 방식이며, IoC를 실현하는 대표적인 기법입니다.
- 생성자 주입에 대한 이해가 중요해요. 생성자 주입은 필수 의존성을 명확히 표현하고 객체 불변성을 보장하며 테스트 코드 작성에 유리하기 때문에 권장됩니다.
- Bean 생명주기 개념을 구체적으로 정리하면 좋아요. Bean 생성 시점, 초기화 콜백, 소멸 콜백, 스코프(singleton, prototype 등)를 구분해서 이해하면 좋습니다.
- Spring에서의 장점을 확장해서 이해하면 좋아요. 결합도 감소, 구현체 교체 유연성, 테스트 시 Mock 객체 주입 용이성, 유지보수성 향상으로 이어집니다.
문제2. Spring Bean의 개념과 생명주기(Lifecycle)에 대해 설명하세요.
[SB] [Spring과 Spring Boot]
문제 2-1. 답변
- Bean Spring IoC 컨테이너에 의해 관리되는 객체
- 생명주기 Bean의 생명주기는 컨테이너가 생성부터 소멸까지 전 부분을 관여한다.
문제 2-2. 정리
Spring Bean은 Spring IoC 컨테이너에 의해 생성되고 관리되는 객체로, 애플리케이션의 핵심 요소입니다. 이는 공장에서 만들어지는 부품처럼 Spring 컨테이너가 관리하다가 필요할 때 제공합니다. Bean의 생명주기는 다음과 같은 3단계로 구성됩니다:
- 생성: Spring 컨테이너가 애플리케이션 시작 시 Bean을 생성합니다.
- 초기화: @PostConstruct 어노테이션이나 InitializingBean 인터페이스를 통해 Bean이 초기화되며, 이때 Bean은 사용할 준비가 됩니다.
- 소멸: 애플리케이션 종료 시 @PreDestroy 어노테이션이나 DisposableBean 인터페이스를 통해 Bean이 소멸됩니다.
문제 2-3. 채점 코멘트
| ✔️ Spring Bean의 개념과 역할 설명 | 2/3점 |
| ✔️ Bean 생명주기의 3단계(생성, 초기화, 소멸) 나열 | 1.5/3점 |
| ✔️ 각 단계별 어노테이션과 정확한 설명 | 1/4점 |
✅ 잘한 부분
- Spring IoC 컨테이너에 의해 관리되는 객체라는 핵심 정의를 정확히 적고 있어요. Bean의 가장 기본 개념을 이해하고 있습니다.
- Bean의 생명주기에 컨테이너가 관여한다는 큰 흐름을 알고 있어요. IoC 컨테이너의 역할을 인지하고 있습니다.
❗ 아쉬운 부분
- Bean의 역할 설명이 부족해요. 왜 Bean으로 관리하는지, 애플리케이션에서 어떤 이점을 제공하는지 언급이 필요합니다.
- 생명주기의 단계가 구체적으로 나열되지 않았어요. 생성, 초기화, 소멸의 구분이 드러나지 않습니다.
- 초기화 단계가 빠져 있어요. 생성 이후 Bean이 사용 가능 상태가 되는 과정 설명이 필요합니다.
- 라이프사이클 관련 어노테이션이나 인터페이스(@PostConstruct, @PreDestroy 등)가 전혀 언급되지 않았어요.
📚 더 공부하면 좋은 내용
- Spring Bean의 개념을 다음 요소까지 확장해서 정리하면 좋아요.
- Bean은 단순히 관리되는 객체가 아니라, 스프링 컨테이너가 생성, 의존성 주입, 초기화, 소멸까지 책임지는 객체입니다.
- 애플리케이션의 구성 요소를 재사용 가능하고 일관되게 관리하기 위한 핵심 단위입니다.
- Bean 생명주기의 표준 3단계를 명확히 구분해서 이해하면 좋아요.
- 생성 단계 컨테이너가 Bean 정의 정보를 기반으로 객체 인스턴스를 생성합니다. 생성자 호출이 여기에 해당합니다.
- 초기화 단계 의존성 주입 완료 이후 Bean이 사용 가능한 상태로 준비됩니다. @PostConstruct → 가장 일반적인 초기화 콜백 InitializingBean.afterPropertiesSet() → 인터페이스 기반 초기화 @Bean(initMethod = “…”) → 설정 기반 초기화 메서드 지정
- 소멸 단계 컨테이너 종료 시 Bean 정리 작업 수행 @PreDestroy → 소멸 직전 콜백 DisposableBean.destroy() → 인터페이스 기반 소멸 @Bean(destroyMethod = “…”) → 설정 기반 소멸 메서드 지정
- 의존성 주입(DI)이 생명주기 중 어디에 위치하는지도 함께 정리하면 좋아요. 생성 → DI → 초기화 → 사용 → 소멸 순서입니다.
- Bean Scope도 중요합니다. singleton → 컨테이너 시작부터 종료까지 하나의 인스턴스 유지 prototype → 요청 시마다 새로운 인스턴스 생성, 소멸 관리 방식 차이 존재
문제3. Spring Boot에서 사용되는 Dependency Injection의 세 가지 방식과 각각의 특징을 설명하세요.
[SB] [Spring과 Spring Boot]
문제 3-1. 답변
- 생성자 주입 생성자를 만들어서 주입하므로, 객체 생성 시점에 주입된다.
- final 사용 가능 -> 불변함
- 컨테이너 없이 테스트 가능
- 필드 주입 필드에 바로 주입하는 것으로, 객체 생성 이후에 주입된다.
- setter 주입 setter로 주입하는 것
문제 3-2. 정리
Spring Boot의 Dependency Injection은 다음 세 가지 방식으로 구현할 수 있습니다:
- 생성자 주입
- 가장 권장되는 방법입니다.
- 의존성이 변경 불가능하도록 보장합니다.
- final 키워드를 사용할 수 있어 불변성을 보장합니다.
- 세터 주입
- 선택적인 의존성을 처리할 때 유용합니다.
- @Autowired 어노테이션과 함께 setter 메서드를 사용합니다.
- 의존성을 런타임에 변경할 수 있습니다.
- 필드 주입
- 가장 간단한 방식이지만 권장되지 않습니다.
- 테스트와 리팩토링이 어렵다는 단점이 있습니다.
- @Autowired 어노테이션을 필드에 직접 사용합니다.
문제 3-3. 채점 코멘트
| ✔️ 세 가지 주입 방식 나열 | 3/3점 |
| ✔️ 각 주입 방식의 구현 방법과 특징 설명 | 2/4점 |
| ✔️ 권장되는 방식과 그 이유 설명 | 2/3점 |
✅ 잘한 부분
- 생성자 주입, 필드 주입, setter 주입을 정확히 나열하고 있어요.
- 생성자 주입이 객체 생성 시점에 이루어진다는 점을 올바르게 설명했습니다.
- final 사용 가능 → 불변성 확보 개념을 잘 이해하고 있어요.
- 컨테이너 없이 테스트 가능하다는 장점을 잘 언급했습니다.
❗ 아쉬운 부분
- 필드 주입의 설명이 매우 간략하여 구현 방식과 특징이 드러나지 않아요.
- setter 주입 역시 동작 방식과 사용 목적 설명이 부족합니다.
- 권장 방식이 무엇인지 명확히 서술되어 있지 않아요.
- 필드 주입의 단점(테스트 제약, final 사용 불가 등)이 빠져 있습니다.
📚 더 공부하면 좋은 내용
- 생성자 주입 특징 정리입니다. 필수 의존성 강제 final 필드 선언 가능 @Autowired 생략 가능(단일 생성자)
- setter 주입 특징입니다. 선택적 의존성 처리 런타임 변경 가능 @Autowired / @Nullable 활용
- 필드 주입 이해입니다. @Autowired 필드 직접 주입 Reflection 기반 동작 테스트 시 Mock 주입 어려움
- 권장 방식 기준입니다. 생성자 주입 권장 불변성 유지 의존성 명시성 확보
문제4. Controller, Service, Repository 각 계층의 역할과 계층화를 통해 얻을 수 있는 이점을 설명하세요.
[SB] [Spring과 Spring Boot]
문제 4-1. 답변
- Cotroller : HTTP 요청/응답 처리
- Service : 비즈니스 로직 처리
- Repository : 데이터에 직접적인 접근
각 계층마다 책임을 분리하여 단일 책임 원칙 준수 가능
문제 4-2. 정리
Spring MVC의 각 계층은 다음과 같은 역할과 책임을 가집니다:
- Controller 계층
- 사용자의 HTTP 요청을 가장 먼저 받아들이고 응답을 반환합니다.
- 요청 데이터의 기본적인 검증을 수행합니다.
- Service 계층으로 비즈니스 로직 처리를 위임하고, 그 결과를 적절한 응답 형태로 변환합니다.
- Service 계층
- 애플리케이션의 핵심 비즈니스 로직을 처리합니다.
- 데이터의 유효성 검사와 비즈니스 규칙을 적용합니다.
- 트랜잭션 관리를 담당하며, Repository 계층과 협력하여 데이터를 처리합니다.
- Repository 계층
- 데이터베이스와의 실제 통신을 담당합니다.
- 데이터의 저장, 조회, 수정, 삭제 등 영속성 작업을 수행합니다.
- 데이터베이스 관련 로직을 다른 계층으로부터 분리하여 관리합니다.
이러한 계층화를 통해 다음과 같은 이점을 얻을 수 있습니다:
- 관심사의 분리
- 각 계층이 자신의 고유한 책임만을 담당하여 코드의 복잡도가 낮아집니다.
- 특정 계층의 구현 변경이 다른 계층에 미치는 영향이 최소화됩니다.
- 계층별 독립적인 개발과 수정이 가능해집니다.
- 유지보수성과 재사용성
- 코드의 구조가 명확해져 버그 수정과 기능 추가가 용이해집니다.
- 각 계층의 코드를 다른 프로젝트에서 재사용하기 쉬워집니다.
- 특정 계층의 구현을 변경하더라도 인터페이스가 유지되면 다른 계층은 수정할 필요가 없습니다.
- 테스트 용이성
- 각 계층을 독립적으로 테스트할 수 있습니다.
- 계층 간 의존성을 모의 객체로 대체하여 단위 테스트가 용이해집니다.
- 통합 테스트와 단위 테스트의 구분이 명확해집니다.
문제 4-3. 채점 코멘트
| ✔️ 각 계층의 핵심 역할과 책임 설명 | 3/4점 |
| ✔️ 계층화를 통해 얻을 수 있는 구체적인 이점 설명 | 2/3점 |
| ✔️ 계층 간 상호작용과 데이터 흐름 설명 | 2/3점 |
✅ 잘한 부분
- 각 계층(Cotroller, Service, Repository)의 핵심 역할을 간결하게 잘 구분하고 있어요.
- 계층별 책임 분리를 통해 단일 책임 원칙(SRP)을 준수할 수 있다는 점을 언급한 점이 좋습니다.
- HTTP 요청/응답과 비즈니스 로직, 데이터 접근의 역할을 정확히 연결하고 있어요.
❗ 아쉬운 부분
- 계층 간 실제 데이터 흐름과 상호작용 과정이 구체적으로 설명되지 않았어요.
- Service와 Repository 간 트랜잭션 처리나 데이터 위임 과정에 대한 언급이 없어 전체 구조 이해가 다소 부족해 보여요.
- 계층화로 인한 유지보수성, 재사용성, 테스트 용이성 등 구체적 장점 설명이 조금 더 보완되면 좋겠어요.
📚 더 공부하면 좋은 내용
- Controller → Service → Repository의 요청/응답 흐름을 실제 예시와 함께 정리하면 이해가 깊어질거에요.
- 트랜잭션 관리, 예외 처리와 같은 Service 계층의 추가 책임에 대해서도 학습해보면 좋아요.
- 단위 테스트와 통합 테스트에서 각 계층이 어떻게 독립적으로 테스트될 수 있는지 사례를 살펴보면 이해가 확장돼요.
문제5. Spring MVC의 핵심 구성 요소인 Model, View, Controller의 역할과 각 요소 간의 상호작용 과정, 그리고 MVC 패턴의 장점을 설명하세요.
[SB] [Spring과 Spring Boot]
문제 5-1. 답변
- Model : 클라이언트의 요청을 처리
- View : 사용자에게 보여지는 화면
- Cotroller : 클라이언트의 요청을 받는 엔드포인트
요청 -> Controller -> Model -> Controller -> View
- 장점 관심사 분리로, 코드 수정 범위가 감소됨 단위 테스트 가능
문제 5-2. 정리
Spring MVC의 각 구성 요소는 다음과 같은 역할을 수행합니다:
- Model
- 애플리케이션의 데이터와 비즈니스 로직을 포함합니다.
- Controller로부터 받은 데이터를 처리하고 가공합니다.
- View에 표시될 데이터를 담는 컨테이너 역할을 합니다.
- 상태 변경과 관련된 비즈니스 규칙을 구현합니다.
- View
- 사용자에게 보여질 화면을 생성합니다.
- Model이 가진 데이터를 적절한 형식으로 표현합니다.
- 웹 애플리케이션의 경우 HTML, JSON, XML 등의 형태로 데이터를 표현할 수 있습니다.
- 실제 비즈니스 로직은 포함하지 않고 순수하게 화면 표현에만 집중합니다.
- Controller
- 사용자의 요청을 가장 먼저 받는 진입점입니다.
- 요청을 분석하고 적절한 Model에 작업을 위임합니다.
- Model에서 처리된 데이터를 View에 전달합니다.
- HTTP 요청과 응답을 처리하고 관리합니다.
요청부터 응답까지의 처리 과정은 다음과 같습니다:
- 사용자가 요청을 보내면 Controller가 이를 받습니다.
- Controller는 필요한 비즈니스 로직을 Model에 위임합니다.
- Model은 데이터를 처리하고 결과를 Controller에 반환합니다.
- Controller는 처리된 데이터를 View에 전달합니다.
- View는 전달받은 데이터를 사용자에게 보여질 형태로 변환합니다.
- 최종적으로 변환된 View가 사용자에게 반환됩니다.
MVC 패턴은 다음과 같은 이점을 가집니다:
- 관심사의 분리를 통한 코드의 유지보수성 향상
- 각 구성 요소의 재사용성 증가
- 화면과 비즈니스 로직의 독립적인 개발 가능
- 테스트 용이성 향상
문제 5-3. 채점 코멘트
| ✔️ 각 구성 요소(Model, View, Controller)의 핵심 역할 설명 | 2/4점 |
| ✔️ 요청부터 응답까지의 데이터 흐름과 처리 과정 설명 | 2/3점 |
| ✔️ MVC 패턴을 사용함으로써 얻을 수 있는 이점 설명 | 2/3점 |
✅ 잘한 부분
- View를 사용자에게 보여지는 화면으로 올바르게 설명하고 있어요.
- Controller를 요청을 받는 엔드포인트로 이해하고 있어요.
- 요청 → Controller → Model → View 흐름을 구조적으로 표현하고 있어요.
- 관심사 분리와 단위 테스트 가능성을 장점으로 언급하고 있어요.
❗ 아쉬운 부분
- Model을 “클라이언트의 요청을 처리”라고 설명한 부분은 정확하지 않아요.
- 요청 처리는 Controller의 역할이며, Model은 데이터와 비즈니스 로직, View 전달 데이터를 담당해요.
- Controller의 설명에서 응답 생성, Model 전달, View 선택 역할이 빠져 있어요.
- 데이터 흐름 설명이 단순 화살표 수준으로 축약되어 있어요.
📚 더 공부하면 좋은 내용
- Model의 책임을 데이터 보관, 상태 전달, 비즈니스 로직 관점으로 정리해보면 좋아요.
- Controller의 책임을 요청 수신, 로직 위임, Model 구성, View 선택 관점으로 복습하면 좋아요.
- DispatcherServlet, HandlerMapping, ViewResolver 흐름을 함께 이해하면 좋아요.
- MVC 장점을 재사용성, 개발 역할 분리 측면에서도 정리해보면 좋아요.
Leave a comment