Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
66ad03e
docs: 3주차 리드미 작성
xxxjinn Apr 30, 2025
810c0f2
docs: 3주차 리드미 작성
xxxjinn May 7, 2025
c0039d7
docs: Bean 개념 작성
xxxjinn May 7, 2025
a09332e
docs: Bean Lifecycle 작성
xxxjinn May 7, 2025
fada9b8
docs: 스프링 어노테이션 작성
xxxjinn May 7, 2025
c561744
docs: 스프링 의존성 주입 방식 작성
xxxjinn May 7, 2025
f4c84ea
docs: 생성자 주입 방식 작성
xxxjinn May 7, 2025
82c2465
docs: 6주차 리드미 작성
xxxjinn May 7, 2025
da7f8e1
Merge remote-tracking branch 'origin/main'
xxxjinn May 7, 2025
ab72184
docs: 7주차 과제 작성
xxxjinn May 11, 2025
6c54c24
docs: 8주차 과제 작성
xxxjinn May 16, 2025
3ca307d
feat: member crud 구현
xxxjinn May 16, 2025
4ecdf12
feat: post crud 구현
xxxjinn May 16, 2025
a96cfe2
refactor: Post - Member ManyToOne 어노테이션 추가
xxxjinn May 16, 2025
f3e5d69
feat: comment crud 구현
xxxjinn May 16, 2025
b50e242
refactor: toEntity 메서드 request dto에서 구현
xxxjinn May 17, 2025
8488fcf
refactor: member에 OneToMany 어노테이션 추가
xxxjinn May 17, 2025
ea02ef3
refactor: post에 OneToMany 어노테이션 추가
xxxjinn May 17, 2025
2764cd0
refactor: comment 엔드포인트 수정
xxxjinn May 17, 2025
c9d40b2
refactor: 줄바꿈 수정
xxxjinn May 19, 2025
336c6d8
refactor: @RequestMapping 사용
xxxjinn May 19, 2025
89124e5
refactor: controller 내부 메서드명 변경
xxxjinn May 19, 2025
6a419c0
refactor: @AllArgsConstructor 사용
xxxjinn May 19, 2025
120d959
refactor: comment 엔드포인트 수정
xxxjinn May 19, 2025
6bdb747
refactor: null 검증 dto에서 수행
xxxjinn May 20, 2025
d4a7ea0
refactor: post update 메서드명 수정
xxxjinn May 20, 2025
8e52430
refactor: dto 패키지 위치 수정
xxxjinn May 20, 2025
174a9e1
refactor: lazy loading 관련 수정
xxxjinn May 20, 2025
ef0af09
docs: 도커파일 추가
xxxjinn May 22, 2025
09507d1
feat: workflows 파일 추가
xxxjinn May 22, 2025
a67ca52
refactor: deploy 파일 수정
xxxjinn May 22, 2025
977cf99
refactor: 버전이 없는 파일 push
xxxjinn May 22, 2025
fb0ee86
refactor: deploy 파일 수정
xxxjinn May 22, 2025
d8e4d06
test: ci/cd 자동화 테스트를 위한 수정
xxxjinn May 22, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
name: Deploy to EC2 with Docker

on:
push:
branches:
- main

jobs:
deploy:
runs-on: ubuntu-latest

steps:
- name: Checkout code
uses: actions/checkout@v3

- name: Set up JDK 17
uses: actions/setup-java@v3
with:
distribution: 'temurin'
java-version: '17'

- name: Grant execute permission to gradlew
run: chmod +x gradlew
working-directory: week8/hyunjin-crud-api

- name: Build with Gradle
run: ./gradlew build --no-daemon
working-directory: week8/hyunjin-crud-api

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3

- name: Log in to Docker Hub
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKER_USERNAME }}
password: ${{ secrets.DOCKER_PASSWORD }}

- name: Build and push Docker image
run: |
docker buildx build \
--platform linux/amd64 \
-t ${{ secrets.DOCKER_USERNAME }}/hyunjin-crud-api:latest \
--push .
working-directory: week8/hyunjin-crud-api

- name: Deploy to EC2
uses: appleboy/[email protected]
with:
host: ${{ secrets.EC2_HOST }}
username: ${{ secrets.EC2_USER }}
key: ${{ secrets.EC2_SSH_KEY }}
script: |
docker pull ${{ secrets.DOCKER_USERNAME }}/hyunjin-crud-api:latest
docker stop spring-app || true
docker rm spring-app || true
docker run -d --name spring-app -p 8080:8080 ${{ secrets.DOCKER_USERNAME }}/hyunjin-crud-api:latest
250 changes: 250 additions & 0 deletions week6/[6주차]신현진.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,250 @@
### Spring MVC Lifecycle
(Request) => Filter -> DispatcherServlet -> HandlerMapping -> HandlerInterceptor -> Controller -> Service -> Repository -> ViewResolver


- **Filter**
- 웹 요청이 들어올 때 맨 처음 가로채서, 필요한 검사나 설정을 하고 난 후 다음 단계로 넘기는 역할
- 인증/인가: 로그인 했는지 확인 후, 안했으면 리다이렉트
- 로깅: 요청 URL, 요청자 IP 등을 로그로 남김
- 인코딩 설정
- 보안 검사: XSS나 SQL Injection에 대한 간단 필터링
- SQL Injection: 사용자가 쿼리문 안에 악의적인 코드를 주입해 DB를 속이는 공격
- CORS 설정


- **DispatcherServlet**
- HandlerMapping에게 요청을 어떤 Controller가 처리해야 하는지를 물어봄
- HandlerMapping이 알려준 Controller를 호출함

- **HandlerMapping**
- DispatcherServlet이 받은 요청에 대해 어떤 Controller가 처리할지를 결정함

- **HandlerInterceptor**
- Controller 앞에 있는 문지기 역할
- 다음 타이밍에 개입 가능
- preHandle(): 컨트롤러가 실행되기 직전
- posthandle(): 컨트롤러 실행 직후, 뷰 렌더링 전
- afterCompletion(): 뷰 렌더링까지 완료된 후

- 흐름 순서
- 요청 -> Filter -> DispatcherServlet -> HandlerInterceptor (preHandle) -> Controller 실행 -> HandlerInterceptor (postHandle) -> View 렌더링 -> HandlerInterceptor (afterCompletion) -> 응답 반환

- **Controller**
- 요청과 매핑되는 곳
- 어떤 로직으로 처리할 것인지 결정하고 그에 맞는 Service를 호출함

- **Service**
- 데이터 처리 및 가공을 위한 비즈니스 로직을 수행
- 요청에 대한 실질적인 로직을 수행함
- Repository를 통해 DB에 접근해 데이터의 CRUD를 처리함

- **Repository**
- DB에 접근하는 객체
- DAO(Data Access Ovject)의 발전된 개념
- DB 접근 뿐 아니라 도메인 중심 아키텍처에 어울리게 설계된 Spring 스타일의 DAO
- Service에서 DB에 접근할 수 있게 해 데이터의 CRUD를 도와줌

- **ViewResolver**
- Controller에서 준 뷰의 이름을 DispatcherServlet으로부터 넘겨받음
- 해당 뷰를 렌더링하고 DispatcherServlet으로 리턴
- DispatcherServlet에서는 해당 뷰 화면을 응답
- View 없이 데이터만 전달하는 경우 ViewResolver는 불필요함


### Dispatcher servlet의 역할
1. 요청 수신
- 클라이언트의 HTTP 요청을 Filter 다음으로 받음
2. 요청 URL에 따라 HandlerMapping에게 어떤 Controller가 해당 요청을 처리할지 물어봄
3. HandlerAdapter 호출
- 해당 Controller를 실제로 실행할 수 있는 방법을 HandlerAdapter에게 위임해 호출함
4. Controller 실행
5. ViewResolver로 어떤 화면을 보여줄지 결정
6. 클라이언트에게 최종 응답

### Bean이란?
스프링이 관리하는 객체(인스턴스)
- 개발자가 new 키워드로 직접 만드는 객체가 아니라 스프링이 자동으로 생성하고 관리하는 객체


- 특징
- 객체의 생명주기를 스프링이 책임짐
- 필요할 때 자동 주입 가능
- 전역적으로 공유되어 사용됨

```
@Component // Bean으로 등록됨
public class UserService {
...
}

```

```
@Configuration
public class AppConfig {
@Bean
public UserService userService() {
return new UserService();
}
}
```


### Bean Lifecycle
스프링 컨테이너가 Bean을 생성/초기화/사용/소멸시키기까지의 전 과정

1. 객체 생성
- 스프링이 객체 인스턴스를 만듦
2. 의존성 주입
- @Autowired, 생성자 주입 등을 통해 필요한 의존 객체를 주입
3. 초기화
- 초기 설정 작업 진행
4. 사용
- 실제로 해당 Bean을 다른 컴포넌트에서 사용
5. 소멸
- @PreDstrosy 등이 호출되어 정리 작업이 수행됨


### Spring 어노테이션 10가지와 그에 대한 설명
**@Component**
- 스프링이 Bean으로 등록할 수 있게 해주는 클래스 표시용 어노테이션

**@Service**
- 비즈니스 로직을 담는 서비스 계층 클래스에 붙임
- 내부적으로는 @Component와 같지만 의미적으로 구분함

**@Repository**
- DAO 역할을 하는 클래스에 붙임
- @Component와 같지만, 데이터 접근 예외를 스프링 예외로 변환해줌

**@Controller**
- 웹 요청을 처리하는 클래스에 붙임
- 스프링 MVC에서 클라이언트 요청을 받는 진입점

**@RestController**
- @Controller + @ResponseBody
- JSON 형태로 데이터를 반환하는 API 작성 시 사용

**@Autowired**
- 필요한 Bean을 자동 주입
- 생성자, 필드, 메서드에 붙일 수 있음

**@Qualifier**
- @Autowired와 함께 사용할 때, 여러 Bean 중 어떤 Bean을 주입할 지 이름으로 지정함

**@Value**
- 환경 변수에서 값을 읽어 주입할 때 사용

**@Configuration**
- 설정 클래스를 나타냄
- 내부에서 @Bean을 사용해 수동으로 Bean을 등록하는 것이 가능

**@Bean**
- 메서드에 붙임
- 직접 생성한 객체를 Bean으로 등록할 때 사용
- @Configuration 클래스 내부에서 사용함


### Spring 의존성 주입 방식
- **생성자 주입(Constructor Injection)**: 생성자를 통해 의존성을 주입 (생성자에 @Autowired)

```
@Component
public class OrderService {

private final PaymentService paymentService;

@Autowired // 생략 가능 (스프링 4.3 이상이면 1개 생성자는 자동으로 주입됨)
public OrderService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
```
- 장점
- final로 불변성을 보장
- mock 객체를 주입하는 것이 가능해져 테스트 용이
- 컴파일 시간에 오류가 잡힘
- 단점
- 의존성이 많을 때 생성자의 매개변수가 길어짐


- **필드 주입(Field Injection)**: @Autowired로 필드에 직접 주입

```
@Component
public class OrderService {

@Autowired
private PaymentService paymentService;
}
```
- 장점
- 코드가 짧아서 간단한 구조를 가짐
- 러닝커브가 작음
- 단점
- private이기 때문에 mock으로 주입이 어려워 테스트에 어려움
- final을 사용하지 못하기 때문에 불변성이 보장 X
- 스프링 컨테이너가 없이는 사용이 불가하기 때문에 다른 환경에서의 사용이 어려워짐


- **세터 주입(Setter Injection)**: @Autowired가 붙은 setter 메서드로 주입

```
@Component
public class OrderService {

private PaymentService paymentService;

@Autowired
public void setPaymentService(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
```
- 장점
- 선택적으로 의존성을 주입하는 것이 가능
- setter를 통해 Mock을 주입하는 것이 가능하기 때문에 테스트가 가능
- 단점
- 의존성이 필수인지 선택인지 명확하지 않음
- 객체가 완전히 세팅되기 전까지는 불안정한 상태임


- **일반 메서드 주입(Method Injection)**: 직접 만든 메서드에 의존성 주입

```
@Component
public class OrderService {

private PaymentService paymentService;

@Autowired
public void init(PaymentService paymentService) {
this.paymentService = paymentService;
}
}
```
- 장점
- 설정 처리나 초기화 로직 등과 함께 의존성을 주입할 때 유용
- 단점
- 코드 가독성이 떨어짐


### 생성자 주입 방식(중요)
필요한 의존 객체를 생성자를 통해 주입받는 방식 => 객체가 생성될 때 부터 의존성을 강제하고, 안정적으로 주입받는 것이 가능

- Lombok 라이브러리 활용 시

```
@RequiredArgsConstructor
@Service
public class OrderService {

private final UserRepository userRepository;
private final OrderRepository orderRepository;

// 생성자가 자동 생성되고, 스프링이 알아서 주입해줌
}
```
-> final 필드만 생성자 파라미터로 포함됨 => 불변성이 보장됨

=> 스프링이 권장하는 가장 안전하고 테스트하기 쉬운 의존성 주입 방식
Loading