Skip to content

[23기_황신애] spring tutorial 미션 제출합니다. #4

Open
shinae1023 wants to merge 7 commits intoCEOS-Developers:shinae1023from
shinae1023:shinae1023
Open

[23기_황신애] spring tutorial 미션 제출합니다. #4
shinae1023 wants to merge 7 commits intoCEOS-Developers:shinae1023from
shinae1023:shinae1023

Conversation

@shinae1023
Copy link

No description provided.

README.md Outdated

## 1. POJO란?

**POJO (Plain Old Java Objection) : 특정 기술이나 프레임워크에 종속되지 않은 순수한 자바 객체**
Copy link

@whc9999 whc9999 Mar 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Object가 Objection으로 오타가 난 것 같아요! 😆
Object로 살짝 수정해 주시면 완벽할 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

네엥 ㅎㅎ

Comment on lines +47 to +55
### 3) 스프링과 POJO의 관계

스프링 프레임워크의 가장 큰 목표 : POJO를 이용한 엔터프라이즈 애플리케이션 개발

개발자는 비즈니스 로직에만 집중해서 순수한 POJO 클래스를 작성하고, 스프링은 그 뒤에서 다음과 같은 기술로 기능을 덧붙여줌

- **IoC/DI :** 순수한 객체 상태로 있으면 필요한 의존성(객체)을 알아서 주입
- **AOP :** 비즈니스 로직에만 집중해서 개발하면 트랜잭션이나 로깅 같은 공통 기능을 밖에서 감싸줌
- **PSA :** 인터페이스만 보고 개발하면 뒤에서 기술이 바뀌어도(DB, 서버 등) 코드 변화 없음
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순히 POJO의 정의만 적은 게 아닌, 스프링의 핵심 3대 요소가 POJO와 어떻게 연결되는지도 얘기해주셔서 이해하기 더 쉬웠습니다! 깔끔하고 느좋 정리 감사합니다!


1. **extends 하지 않기:** 특정 규약(Framework)의 클래스를 상속받지 않음
2. **implements 하지 않기:** 특정 규약의 인터페이스를 구현하지 않음
3. **종속되지 않기:** 특정 환경에 종속적인 어노테이션이나 라이브러리가 비즈니스 로직에 침투하지 않음
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

실무에서 자주 쓰는 @service, @RestController나 JPA의 @entity 같은 어노테이션이 붙은 클래스들은 엄밀히 따지면 특정 기술에 종속된 것이기 때문에 완벽한 POJO라 부르기 힘들 것 같은데 스프링에서는 이를 POJO 지향적인 개발이라고 부르는 이유가 뭘지 나중에 같이 얘기 나눠봐요!!

Comment on lines +602 to +615
### **5-3) @Repository가 없어도 되는 이유**

1. **자동 프록시 생성 (Proxy Mechanism)**
- **동적 생성** : 개발자가 인터페이스만 선언하면, 스프링 데이터 JPA가 런타임에 해당 인터페이스의 구현체(프록시 객체)를 자동으로 만들어줌.
- **자동 등록** : 이 과정에서 생성된 프록시 객체를 스프링이 알아서 빈으로 등록하기 때문에 별도의 어노테이션이 필요 없음.
2. **@EnableJpaRepositories의 역할**
- **스캔 기능** : 스프링 부트 메인 클래스 등에 (보이지 않게) 설정된 `@EnableJpaRepositories`가 특정 패키지 내에서 `Repository` 인터페이스를 상속받은 모든 인터페이스를 찾아냄.
- **타입 기반 탐색** : 어노테이션이 있냐 없냐보다, `JpaRepository`를 상속받았느냐를 기준으로 빈 등록 대상을 결정함.
3. **@NoRepositoryBean의 정체**
- **정의** : "이 인터페이스는 실제 리포지토리 빈으로 만들지 마라"고 스프링에게 알리는 표식
- **방지책** : 스프링 데이터 JPA는 리포지토리 인터페이스를 스캔할 때, 해당 인터페이스가 실제 데이터베이스와 연결된 리포지토리인지 아니면 단순히 기능을 물려주기 위한 중간 인터페이스인지 구분해야 함.
- JpaRepository에 붙어 있는 이유
- **공통 인터페이스 보호** : `JpaRepository`는 모든 엔티티에 공통으로 쓰이는 메서드(`save`, `findAll` 등)를 정의한 인터페이스일 뿐, 특정 엔티티(예 : User, Order)를 위한 리포지토리가 아님
- **오류 방지** : 만약 여기에 `@NoRepositoryBean`이 없다면, 스프링은 `JpaRepository` 자체를 빈으로 만들려고 시도하다가 "이건 어떤 엔티티용 리포지토리야?"라며 에러 발생
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

JPA를 처음 쓸 때 인터페이스만 만들고 동작하는게 신기했는데, @NoRepositoryBean의 역할과 스프링 데이터 JPA의 자동 프록시 생성 메커니즘을 이렇게 뜯어볼 수 있어 너무 좋았습니다! 프레임워크의 내부 동작을 짚고 넘어가 주셔서 튜토리얼 복습에 큰 도움이 되었습니다~!


- **소스 :** 과거에는 XML을 많이 썼지만, 현재는 자바 설정 클래스(`@Configuration`)와 어노테이션(`@Component`, `@Autowired`)을 주로 사용
- **역할 :** 이 가이드북을 해석해서 어떤 객체를 싱글톤으로 만들지, 어떤 구현체를 주입할지 결정
4. BeanFactory vs ApplicationContext
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

스프링 컨테이너의 역할에 대해서 잘 설명해주셨습니다! 근데 4. BeanFactory vs ApplicationContext 이 부분의 제목 포맷팅이 살짝 깨진 것 같아서 리뷰 남깁니다! 설명 너무 잘 읽었습니다~!

Comment on lines +704 to +725
### 2-1) 싱글톤을 무상태로 설계하는 이유

- 상태 유지 설계의 문제점
- **공유 필드 발생**: 여러 스레드가 동시에 값을 변경하면 데이터가 뒤섞임
- **예상치 못한 결과**: 사용자 A의 주문 금액이 사용자 B에 의해 덮어씌워지는 사고 발생

```java
@Component
public class StatefulService {

private int price; // 상태를 유지하는 필드 (문제 발생 지점)

public void order(String name, int price) {
System.out.println("name = " + name + " price = " + price);
this.price = price; // 여기서 특정 사용자의 상태를 필드에 저장함
}

public int getPrice() {
return price; // 저장된 필드 값을 반환함
}
}
```
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

싱글톤 빈의 무상태 설계 중요성을 명확하게 설명해주신 것 같습니다!
읽다가 만약 싱글톤 빈 내부에서 프로토타입 빈을 주입받아 사용한다면, 해당 프로토타입 빈은 매 요청마다 새로 생성 될 지, 혹은 싱글톤처럼 처음에 생성된 하나만 계속 유지 될 지 궁금증이 생겼습니다.
백엔드 기술 면접에서도 많이 나오는 내용이라고 봤었던 것 같은데 같이 공부해보면 좋을 것 같아요!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

싱글톤 빈의 무상태 설계 중요성을 명확하게 설명해주신 것 같습니다! 읽다가 만약 싱글톤 빈 내부에서 프로토타입 빈을 주입받아 사용한다면, 해당 프로토타입 빈은 매 요청마다 새로 생성 될 지, 혹은 싱글톤처럼 처음에 생성된 하나만 계속 유지 될 지 궁금증이 생겼습니다. 백엔드 기술 면접에서도 많이 나오는 내용이라고 봤었던 것 같은데 같이 공부해보면 좋을 것 같아요!

감사합니다! 흐음 그냥 생각해봤을땐 처음에 생성된 하나만 계속 유지되어야 맞을거 같은데! 좀 더 공부해보고 정리한 내용 나중에 반영해볼게요~

Copy link

@Seungwon326 Seungwon326 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

코드 리뷰 완료했습니다!
고생 많으셨습니다!!

// ...
}
```

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

POJO인 경우와 아닌 경우를 코드 예시를 들어 설명해주시니 이해하기가 쉬웠습니다!

- **코드의 단순화 :** 프레임워크 관련 코드가 사라져 가독성이 좋아짐
- **테스트 난이도 하락 :** 환경의 영향을 받지 않으므로 JUnit 등을 이용해 빠르게 단위 테스트 가능
- **객체지향적 설계 :** 특정 기술의 제약이 없으므로 객체지향 설계(상속, 다형성 등)를 적용하기 쉬움

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

저는 이번 README에 POJO에 관해서는 넣지 않았는데 신애님 덕분에 한 번 더 복기 할 수 있어서 좋았습니다!


- 가장 권장되는 방식

### 3-3) 생성자 주입이 가장 권장되는 이유

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

가장 권장되는 방식이 무엇인지만 알려주고 끝나는게 아닌 이유까지 자세하게 설명해줘서 해당 방식을 더 쉽게 이해하고 납득 할 수 있었습니다!

7. **인터셉터 후처리 (applyPostHandle)** : 로직 수행 후, 뷰 렌더링 전에 인터셉터의 `postHandle`을 실행함
8. **뷰 렌더링 (processDispatchResult)** : `ViewResolver`를 통해 논리적 뷰 이름을 실제 뷰 객체로 변환하고 화면을 생성하여 응답함

**코드 구조**

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

단순하게 글로만 설명을 적은 것이 아닌 예시 코드도 넣어주셔서 훨씬 이해가 쉬웠습니다!
저도 앞으로 개념 설명할 때 예시 코드를 넣는 습관을 가져야겠네요..

Copy link
Member

@Hoyoung027 Hoyoung027 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

리드미가 너무 잘 작성되어 있어서 저도 좋은 공부가 된 것 같습니다 👍
잘하시는만큼 조금 더 디테일 한 내용 몇가지를 리뷰로 남겨두었으니 공부해보시고 스터디원 분들과 이야기해보면 좋을 것 같아요~! 수고 많으셨습니다!!

```java
protected void doDispatch(HttpServletRequest request, HttpServletResponse response) throws Exception {
// 1. 핸들러 결정
mappedHandler = getHandler(processedRequest);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mappedHandler의 자료형을 보시면 HandlerExecutionChain인데요, 여기에는 무엇이 담겨있는걸까요? 왜 Chain이라고 부르는걸까요?

한번 찾아보시면 좋을 듯 합니다!


// 2. 핸들러 어댑터 결정
HandlerAdapter ha = getHandlerAdapter(mappedHandler.getHandler());

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

mappedHandler로 핸들러를 찾았음에도 불구, Adapter가 추가로 필요한 이유는 뭘까요?

// 6. 결과 처리 및 뷰 렌더링
processDispatchResult(processedRequest, response, mappedHandler, mv, dispatchException);
}
```
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

개인적으로 뷰 렌더링이 익숙한 표현은 아니었는데요, 프론트와 백의 역할이 구별되기 시작하면서 백엔드에서 화면을 그려내는 일을 더이상 하지 않게 되었기 때문인 듯 합니다.

그렇다면 여기에서 뷰 렌더링 로직은 어떻게 짜여져 있는걸까요??

@RestController, @Controller의 동작 차이를 알아보시면 좋을 것 같습니다!

@shinae1023
Copy link
Author

코드 리뷰 완료했습니다! 고생 많으셨습니다!!

감사합니다 !!

@shinae1023
Copy link
Author

리드미가 너무 잘 작성되어 있어서 저도 좋은 공부가 된 것 같습니다 👍 잘하시는만큼 조금 더 디테일 한 내용 몇가지를 리뷰로 남겨두었으니 공부해보시고 스터디원 분들과 이야기해보면 좋을 것 같아요~! 수고 많으셨습니다!!

감사합니다! doDispatcher() 에서 자료형의 이름에 주목하진 않았는데 덕분에 mvc에 대해서 좀 더 자세히 공부하는 기회가 되었습니다~

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants