Skip to content

[21기_이석원] spring tutorial 미션 제출합니다. #9

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: leerura
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
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
3 changes: 3 additions & 0 deletions .idea/.gitignore

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions .idea/.name

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

8 changes: 8 additions & 0 deletions .idea/modules.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

9 changes: 9 additions & 0 deletions .idea/spring-tutorial-21st.iml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

111 changes: 109 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,109 @@
# spring-tutorial-21st
CEOS back-end 21st spring tutorial project
Spring Tutorial 21st

CEOS Back-end 21st Spring Tutorial Project

시작하기 앞서...

Spring도 Java도 처음 접하는 입장에서 시행착오를 겪으며 배운 내용을 정리했습니다.
별의별 걸 다 적었다고 느끼실 수도 있지만... 자라나는 새싹을 본다는 마음으로 봐주세용.
Comment on lines +5 to +8

Choose a reason for hiding this comment

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

아자아자 화이팅~!


1. 서버(애플리케이션) 실행

./gradlew bootRun

bootRun 실행 시 SpringApplication.run()을 호출하여 @SpringBootApplication이 붙은 main 클래스를 실행합니다.


2. 서버 실행 확인

브라우저나 curl을 통해 확인 가능

3. 의존성 추가 및 확인

./gradlew dependencies

dependencies 수정했다면 꼭 ./gradlew build --refresh-dependencies 하기

Choose a reason for hiding this comment

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

인텔리제이 쓰시나요? 그러면 아마 gradle을 수정할 때마다 코끼리 모양이 둥둥 떠다닐겁니다! 그거 누르셔도 돼요:)


이거 안 해서 Can't resolve 에러 많이 만났습니다...

Choose a reason for hiding this comment

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

저도 많이 만났습니다 ㅎㅎ...


4. 어노테이션이란?

어노테이션(Annotation)은 Java 코드에 추가적인 정보를 제공하는 특수한 기호입니다. @로 시작하며, 코드의 의미를 설명하고 특정 기능을 자동으로 수행할 수 있도록 도와줍니다.

Choose a reason for hiding this comment

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

사용자 정의 어노테이션을 통해서 원하는 기능을 수행하는 어노테이션을 만들 수 있습니다! 사용자 정의 어노테이션 공부를 통해서 다른 어노테이션 구현체를 확인할 때 도움이 되실 거 같아요!

https://ittrue.tistory.com/158

개발을 할때 어노테이션을 정말 많이 사용하기 때문에 구현체를 봐가면서 공부하는게 전 도움이 되더라고요!


예제:

@RestController // REST API를 처리하는 컨트롤러 선언

Choose a reason for hiding this comment

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

@RestController와 비슷하게 @controller도 있는 것으로 아는데, 이 둘의 차이점과 어떤 걸 주로 쓰는지 알아보면 이후 프로젝트에 적용할 수 있을 것 같습니다!

  • 석원님 글을 읽고 저도 궁금해서 찾아봤습니다

@GetMapping("/") // HTTP GET 요청을 특정 메서드에 매핑

5. 몰랐던 개념 정리

Choose a reason for hiding this comment

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

이렇게 개념 정리하고 가는거 너무 좋아요~~


인터페이스 : 클래스가 구현해야 할 메서드의 틀을 정의하는 것 (규칙 정하기)

빈(Bean) : Spring이 관리하는 객체

Choose a reason for hiding this comment

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

Bean의 라이프 사이클에 대해 알아보셔도 이해에 도움이 될 것 같습니다!

Spring 컨테이너 : 빈들을 생성하고 의존성을 자동으로 주입하는 공간

static : 변수나 메서드가 클래스 자체에 속하며, 객체를 생성하지 않고도 사용 가능

//빈이랑 컨테이너에 대해 더 찾아봤는데 생성, 소멸... 등등 잘 와닿지 않는 내용이 많았습니다.
추가적으로 아래에 더 작성해두었습니다.

6. 단위 테스트(Unit Test)

**단위 테스트(Unit Test)**는 코드의 가장 작은 단위(메서드, 클래스)를 독립적으로 테스트하는 것을 의미합니다.

7. 데이터베이스

Spring Boot 데이터 계층 구성

Domain : 모델 (Entity)

Repository : 데이터 저장소 (JPA, MyBatis 등) DB에서 데이터 가져옴

Service : 로직 처리 , 실제 로직 처리

Comment on lines +57 to +64

Choose a reason for hiding this comment

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

여기서 DTO에 관련된 내용도 추가적으로 찾아보시면 좋을 거 같아요!~!

Choose a reason for hiding this comment

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

DTO를 찾아보면서 DAO와 차이점도 알아두면 좋을 것 같아요. 이름이 비슷해서 저도 늘 헷갈려요..

Controller : REST API 제공 => 요청 받고 응답 반환

//Service와 Controller의 차이 => 데이터베이스 할 때 둘이 비슷하게 생겨서 뭔 차인지 싶어서 찾아보았습니다.
Service가 로직을 처리하는 핵심, Controller는 요청받고 그 요청을 Service에게 전달하고 응답을 보내는 역할이라고 하더군요.
Comment on lines +67 to +68

Choose a reason for hiding this comment

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

저는 처음 이해할 때 service는 장고의 view와 유사하고 controller는 url라고 이해를 했던 거 같아요! 자세하게 들어가면 차이점도 있으니 조금 더 알아보시면 더 쉽게 이해하실 수 있을 거 같아요! 추가적으로 웹 어플리케이션의 다양한 디자인 패턴에 대해서도 공부하면 도움이 될 것 같습니다!

Choose a reason for hiding this comment

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

Service와 Controller가 구분되는 이유를 알기 위해서 MVC 패턴을 찾아보면 어떨까 생각이 듭니다!

Copy link

@wlqgkrry wlqgkrry Mar 16, 2025

Choose a reason for hiding this comment

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

  • MVC 패턴 뿐만 아니라 전체적인 틀이 되는 layerd architecture 내용에 관해 알아봐도 좋을 것 같습니다!
    아래는 제가 참고했던 정보글입니다.
    https://gnuoyus.tistory.com/70

  • 간단히 말해 각자 할 일을 분야별로 나눠서 독립적으로 실행하게 한다는 것인데, 파일명(controller.java, service.java, repository.java, models 등)은 코드 작성자가 쓰기 나름인 것 같았습니다. (비교적 자유롭다는 뜻)

  • 틀릴 수도 있지만 제가 계층에 대해 이해한 바는 아래와 같습니다
  1. controller : 가장 앞단에서 req를 받고 res를 보내는 로직을 처리함. 그 안에서 이루어지는 구현 로직은 service가 담당합니다. request를 받았는데 성공~ 이라면 200을 띄워주고, 아니라면 404 띄워.. 이런 로직을 보통 controller에서 담당합니다.

  2. service : controller 안에 service 계층의 함수를 작성합니다. (controller 실행 이후 바로 구현 로직을 실행해야 하니까) service계층에서 작성되는 함수는 보통 이런 함수들입니다.
    (1) 사진 업로드 하고 싶어 -> 업로드 하는 로직 구현
    (2) 전체 조회를 시킬 건데 request로 받은 id = n일 때에만 전체 조회 시킬래 -> id = n 인지 구별하는 로직 구현

  3. repository : 위로는 service 계층, 아래로는 database 계층과 만나는 계층입니다. controller와 service는 db와 직접적으로 만날 수 없지만 repository에서 db 내용을 수정하는 코드를 작성할 수 있습니다.


  • 코드 리뷰와는 목적이 맞지 않은 설명일까 싶어서... 혹시 그렇다면 편하게 의견을 말씀해주세요! (머쓱)


TMI:

마지막에 테이블 생성이 안 돼서 고생함. 알고 보니 Test 엔티티와 관련된 클래스들이 Application과 같은 패키지에 있어야 했음.

Choose a reason for hiding this comment

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

저는 처음에 H2에 TEST가 안 생기더라고요...
혹시 Appication과 같은 패키지에 있어야 하는 이유도 아시나요?? 저도 공유해주세요 o(TヘTo)


느낀 점: Java 같은 객체지향언어가 처음인데 진짜 다 클래스로 나타내더라고요.
신기했습니다. 아직 Java를 잘 몰라서 모든 코드를 완전 이해한 것은 아니지만 지금부터 차근차근 더 노력해보겠습니다.

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.

저도요.. 저희 함께 화이팅입니다 👍



##스프링이 지원하는 기술

Ioc(Inversion of Control) : 제어역전
객체 생성, 주기 관리를 개발자가 아닌 Spring 컨테이너가 담당
=> Spring이 알아서 해줘서 개발자가 편함(어노테이션을 통해서 구현함.)
Ex. @Component, @Service, @Repositoty, @Controller => Bean 등록록

Choose a reason for hiding this comment

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

이 어노테이션이 어떻게 빈으로 등록되는지 왜 빈으로 등록되는지, 빈이 무엇인지 알아보면 좋을 거 같아요!
component scan이라는 키워드를 통해 공부할 수 있답니다!



DI (Dependency Injection) : 의존성 주입
=> 객체 내부에서 다른 객체를 생성하는 게 아니라 외부에서 주입받음. 따라서 더 유연하게 작업할 수 있음(IoC와 마찬가지로 어노테이션을 통해 구현됨.)
Ex. @Autowired
Comment on lines +86 to +88

Choose a reason for hiding this comment

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

의존성 주입을 하지 않는다면 서로 다른 두 연관된 클래스가 너무 강하게 결합될 수 있다는 문제가 있기 때문에 애플리케이션 실행 시점에 필요한 객체(빈)를 생성하고 두 객체의 연결을 위해 한 객체를 다른 객체로 주입시켜야한답니다!

의존성 주입 방법은 다양하기에 각 방법의 장단점을 잘 비교하고 사용하는게 좋겠죠?? 스프링은 어떤 방법을 권고할까요?
https://lincoding.tistory.com/76


AOP (Aspect-Oriented Programming)

Choose a reason for hiding this comment

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

이건 간단히 설명하면 객체 지향 프로그래밍을 보완하기 위해 사용을 한답니다!
웹 애플리케이션에는 핵심 비즈니스 로직이 있고 부가기능 로직(로깅, 보안, 트랜잭션)이 있습니다.

이런 부가 기능은 핵심 비즈니스 로직과 분리해 코드 간결성을 높이고 유연성, 확장성을 높이기 위해 사용합니다!

https://sharonprogress.tistory.com/195

Choose a reason for hiding this comment

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

저는 AOP 개념이 와닿지 않아서 많이 찾아봤는데 이 영상을 보고 나름 이해했습니다..!
https://youtu.be/hdO_V7EMU4s?si=o0T-tV2iVMGgPN_S
https://youtu.be/Hm0w_9ngDpM?si=Sc_LG8jR4URonlUx


PSA (Portable Service Abstraction)

Choose a reason for hiding this comment

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

PSA는 환경의 변화 관계없이 일관된 기술로 접근 환경을 제공하는 추상화 구조입니다!

이걸 통해서 저희는 기존 코드를 수정하지 않고 확장 가능합니다!
스프링이 어떤 PSA를 제공하고 있는지 알아보면 스프링의 동작 원리를 더 이해하기 쉬우실 거 같아요!


##Spring Bean과 라이프사이클

Spring Bean : Spring 컨테이너가 관리하는 객체 => IoC 구현
=> 어노테이션 등을 사용해서 Bean으로 등록가능

빈이 라이프사이클 :
1. 객체 생성
2. 의존성 주입(by @Autowired)
3. 초기화
4. 사용
5. 소멸
Comment on lines +99 to +104

Choose a reason for hiding this comment

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

이 모든 걸 개발자가 아니라 컨테이너가 해주기에 개발자는 로직에 집중할 수 있답니다!

객체가 필요한 시점에 생성하고 종료 시점에 종료하는 것을 하기 위해서는 객체 생성 뒤 의존성 주입 후 콜백을 통해 초기화 시점을 알려줍니다. 그 후 종료한다면 종료 직전 다시 콜백을 통해 소멸을 진행하게 됩니다! -> 콜백을 통해 각 단계를 원하는 시점에 실행시켜 주기 위함입니다.

특히 생성과 초기화를 콜백으로 분리하는 것은 초기화가 무거운 작업이기에 이를 분리해 유지보수를 고려해준 것입니다!


##어노테이션: 이걸 활용해서 spring이 특정 동작 수행


통합테스트 : 여러 컴포넌트가 함께 동작하는지 검증하는 테스트트
3 changes: 3 additions & 0 deletions spring-boot/.gitattributes
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
/gradlew text eol=lf
*.bat text eol=crlf
*.jar binary
37 changes: 37 additions & 0 deletions spring-boot/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
HELP.md
.gradle
build/
!gradle/wrapper/gradle-wrapper.jar
!**/src/main/**/build/
!**/src/test/**/build/

### STS ###
.apt_generated
.classpath
.factorypath
.project
.settings
.springBeans
.sts4-cache
bin/
!**/src/main/**/bin/
!**/src/test/**/bin/

### IntelliJ IDEA ###
.idea
*.iws
*.iml
*.ipr
out/
!**/src/main/**/out/
!**/src/test/**/out/

### NetBeans ###
/nbproject/private/
/nbbuild/
/dist/
/nbdist/
/.nb-gradle/

### VS Code ###
.vscode/
29 changes: 29 additions & 0 deletions spring-boot/Readme
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@

Controller 작성
어노테이션이란??
=> Java 코드에 추가적인 정보를 제공하는 특수한 기호, @로 시작함,
코드의 의미를 설명하고 자동으로 동작할 수 있도록 설명
ex> @RestController, @GetMapping ...

Application class 수정

인터페이스 => 인터페이스는 클래스가 구현해야 할 메서드의 틀을 정의하는 것.(규칙 정하기)
빈(Bean) => Spring이 관리하는 객체
Spring 컨테이너 => 빈들을 관리하는 공간, 빈들을 생성하고 의존성을 자동으로 주입
static => 변수나 메서드가 클래스 자체에 속하며, 객체를 생성하지 않고도 사용 가능
args => arguments

@SpringBootApplication = @Configuration(Spring 설정 파일) + @EnableAutoConfiguration(필요한 빈들을 자동 등록) + @ComponentScan(현재 패키지에서 Spring 빈을 찾아 등록)

단위 테스트

단위 테스트란 => 코드의 가장 작은 단위(메서드, 클래스)를 독립적으로 테스트하는 것

데이터베이스

TCP란? Transmission Control Protocal

Domain : 모델
Repository : 저장소
Service : 로직 처리
Controller : Rest API
38 changes: 38 additions & 0 deletions spring-boot/build.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
plugins {
id 'java'
id 'org.springframework.boot' version '3.4.3'
id 'io.spring.dependency-management' version '1.1.7'
}

group = 'com.ceos21'
version = '0.0.1-SNAPSHOT'

java {
toolchain {
languageVersion = JavaLanguageVersion.of(21)
}
}

repositories {
mavenCentral()
}

dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
testImplementation 'org.springframework.boot:spring-boot-starter-test'

implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'
runtimeOnly 'com.h2database:h2'

//testImplementation 'org.springframework:spring-test'


//testRuntimeOnly 'org.junit.platform:junit-platform-launcher'

}

tasks.named('test') {
useJUnitPlatform()
}
Binary file added spring-boot/gradle/wrapper/gradle-wrapper.jar
Binary file not shown.
7 changes: 7 additions & 0 deletions spring-boot/gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
Loading