들어가기 앞서
스터디 영상
스터디 자료
안녕하세요~! 백엔드 파트리드 권찬입니다 
2주차 스터디는 지난 학기 진행했던 스터디 내용과 크게 다르지 않아 지난 학기에 따로 녹화했던 영상으로 가져왔습니다.
2주차 스터디에서는 스프링 빈과 어플리케이션 컨텍스트에 대해 정리해보았는데요, 이번 주 내용을 간단하게 요약하면 다음과 같습니다.
스프링 빈 = 어플리케이션 전역에서 공통으로 사용하는 하나의 객체
스프링 컨테이너 = 스프링 빈을 저장하는 공용 저장 공간
의존성 주입 = 필요한 빈을 프레임워크가 컨테이너에서 찾아 대신 넣어주는 것
컨테이너에 빈을 등록하는 방법 : 컴포넌트 스캔, 설정 파일 작성
의존성 주입을 받는 방법 : 생성자 주입, 필드 주입, 메서드 주입
스프링 계층 구조 : 컨트롤러 <-> 서비스 <-> 레포지토리 <-> DB
WIL 을 작성하실 때는 아래 내용을 위주로 정리해보시면 좋을 것 같습니다.
이 내용들은 인터넷에 검색해보시면 많은 사람들이 잘 정리해두었으니 같이 보면서 정리하셔도 좋습니다!
•
스프링 빈과 스프링 컨테이너의 개념
•
스프링 빈을 컨테이너에 저장(등록)하는 방법
•
의존성 주입 (DI) 개념과 스프링에서 의존성을 주입하는 방법
혹시 이와 관련된 내용을 좀 더 깊이 있게 학습하고 싶으시다면, 강의에서 언급드렸듯 인프런에서 김영한 님의 스프링 핵심 원리 - 기본편 강의를 들어보시길 추천드립니다.
과제
목표
•
스프링 빈과 컨테이너의 개념 이해하기
•
스프링 빈을 컨테이너에 등록하는 방법 이해하기
•
컨테이너에 등록된 스프링 빈을 가져오는 방법 이해하기
제출해야 할 파일과 파일 경로
1.
wil.md 파일에 이번 주 학습 내용, 느낀 점 등을 자유롭게 정리해주세요.
2.
스프링의 계층 구조에 맞춰 MyController, MyService, MyRepository 클래스를 만들어 빈으로 등록하고, 의존성을 주입해봅니다.
하단의 예제 코드도 함께 참고해주세요 :)
a.
폴더 구조 명세를 참고하여 main 디렉토리 하위에 hw 패키지를 만들고, 그 안에 MyController, MyService, MyRepository 클래스를 생성합니다.
- 각 클래스는 모두 컴포넌트 스캔 방식을 사용하여 빈으로 등록해주세요.
- MyController 는 MyService에 의존하고, MyService 는 MyRepository에 의존합니다.
각 의존성은 롬복을 사용하여 생성자 주입 방식으로 의존성을 주입해주세요.
(롬복은 @RequiredArgsConstructor, @Getter 등을 제공하는 라이브러리입니다.)
- MyRepository 는 “repository”를 출력하는 public 메서드를 갖습니다.
- MyService 는 “service” 를 출력하고, 위에서 작성한 MyRepository의 메서드를 호출하는 public 메서드를 갖습니다.
- MyController 는 “controller” 를 출력하고, 위에서 작성한 MyService의 메서드를 호출하는 public 메서드를 갖습니다.
b.
폴더 구조 명세를 참고하여 test 디렉토리 밑에 hw 패키지를 만들고 테스트 클래스를 생성합니다.
테스트 클래스에는 @SpringBootTest 어노테이션을 사용하고, 필드 주입 방식으로 MyController 빈을 주입 받아주세요.
- 테스트 메서드에서 주입 받은 MyController 객체의 public 메서드를 호출해주세요. (예시 코드 참고)
- 테스트 실행 결과를 스크린샷으로 찍어 wil.md 파일에 추가해주세요.
(실행 결과 예시 참고)
폴더 구조 명세 (예시)
week2/
└── wil.md
└── 테스트 실행결과 스크린샷 이미지
todoapi/
└── main/
└──── java/
└────── com.example.todoapi/
└──────── hw/
└────────── MyController.java
└────────── MyService.java
└────────── MyRepository.java
└── test/
└──── java/
└────── com.example.todoapi/
└──────── hw/
└────────── MyControllerTest.java
YAML
복사
MyController, MyService, MyRepository 참고용 예시
class MyController {
private MyService myService;
public void controllerMethod() {
System.out.println("contoller");
myService.serviceMethod();
}
}
Java
복사
class MyService {
private MyRepository myRepository;
public void serviceMethod() {
System.out.println("service");
myRepository.repositoryMethod();
}
}
Java
복사
class MyRepository {
public void repositoryMethod() {
System.out.println("repository");
}
}
Java
복사
메서드 이름은 자유롭게 지어주셔도 괜찮습니다.
이 코드는 참고용 코드입니다. 이렇게 그대로 작성하기만 하면 스프링 빈으로 등록해서 사용한 게 아니라 제대로 동작하지 않을 거에요.
이 코드를 참고하여 각 클래스를 컴포넌트 스캔 방식을 사용하여 빈으로 등록하고, 생성자 주입 방식으로 의존성을 주입해주세요.
혹시 참고용 코드를 보셔도 과제 명세가 이해가 안되시거나 궁금한 점이 있으시면 편하게 DM 주세요!
테스트 함수 예시
@Test
public void controllerTest() {
myController.controllerMethod();
}
Java
복사
myController 객체는 필드 주입 방식으로 컨테이너에서 주입 받아 사용합니다.
직접 new 로 객체를 생성해서 호출하시면 안됩니다!
테스트 실행 결과 예시
5:26:01.995 [main] INFO org.springframework.test.context.support.AnnotationConfigContextLoaderUtils -- Could not detect default configuration classes for test class [com.example.todo_api.hw.MyControllerTest]: MyControllerTest does not declare any static, non-private, non-final, nested classes annotated with @Configuration.
15:26:02.052 [main] INFO org.springframework.boot.test.context.SpringBootTestContextBootstrapper -- Found @SpringBootConfiguration com.example.todo_api.TodoApiApplication for test class com.example.todo_api.hw.MyControllerTest
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v3.4.4)
2025-03-30T15:26:02.292+09:00 INFO 67291 --- [todo-api] [ main] c.example.todo_api.hw.MyControllerTest : Starting MyControllerTest using Java 17.0.14 with PID 67291 (started by everdu in /Users/everdu/개인적인/GDSC/2025-1 정규 백엔드 스터디/todo-api)
2025-03-30T15:26:02.293+09:00 INFO 67291 --- [todo-api] [ main] c.example.todo_api.hw.MyControllerTest : No active profile set, falling back to 1 default profile: "default"
2025-03-30T15:26:02.529+09:00 INFO 67291 --- [todo-api] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2025-03-30T15:26:02.537+09:00 INFO 67291 --- [todo-api] [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 5 ms. Found 0 JPA repository interfaces.
2025-03-30T15:26:02.674+09:00 INFO 67291 --- [todo-api] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting...
2025-03-30T15:26:02.751+09:00 INFO 67291 --- [todo-api] [ main] com.zaxxer.hikari.pool.HikariPool : HikariPool-1 - Added connection conn0: url=jdbc:h2:mem:4be521e4-c3bb-4c73-a220-e31f99039d8a user=SA
2025-03-30T15:26:02.752+09:00 INFO 67291 --- [todo-api] [ main] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed.
2025-03-30T15:26:02.774+09:00 INFO 67291 --- [todo-api] [ main] o.hibernate.jpa.internal.util.LogHelper : HHH000204: Processing PersistenceUnitInfo [name: default]
2025-03-30T15:26:02.804+09:00 INFO 67291 --- [todo-api] [ main] org.hibernate.Version : HHH000412: Hibernate ORM core version 6.6.11.Final
2025-03-30T15:26:02.818+09:00 INFO 67291 --- [todo-api] [ main] o.h.c.internal.RegionFactoryInitiator : HHH000026: Second-level cache disabled
2025-03-30T15:26:03.099+09:00 INFO 67291 --- [todo-api] [ main] o.s.o.j.p.SpringPersistenceUnitInfo : No LoadTimeWeaver setup: ignoring JPA class transformer
2025-03-30T15:26:03.133+09:00 INFO 67291 --- [todo-api] [ main] org.hibernate.orm.connections.pooling : HHH10001005: Database info:
Database JDBC URL [Connecting through datasource 'HikariDataSource (HikariPool-1)']
Database driver: undefined/unknown
Database version: 2.3.232
Autocommit mode: undefined/unknown
Isolation level: undefined/unknown
Minimum pool size: undefined/unknown
Maximum pool size: undefined/unknown
2025-03-30T15:26:03.559+09:00 INFO 67291 --- [todo-api] [ main] o.h.e.t.j.p.i.JtaPlatformInitiator : HHH000489: No JTA platform available (set 'hibernate.transaction.jta.platform' to enable JTA platform integration)
2025-03-30T15:26:03.561+09:00 INFO 67291 --- [todo-api] [ main] j.LocalContainerEntityManagerFactoryBean : Initialized JPA EntityManagerFactory for persistence unit 'default'
2025-03-30T15:26:03.626+09:00 WARN 67291 --- [todo-api] [ main] JpaBaseConfiguration$JpaWebConfiguration : spring.jpa.open-in-view is enabled by default. Therefore, database queries may be performed during view rendering. Explicitly configure spring.jpa.open-in-view to disable this warning
2025-03-30T15:26:03.807+09:00 INFO 67291 --- [todo-api] [ main] c.example.todo_api.hw.MyControllerTest : Started MyControllerTest in 1.696 seconds (process running for 2.152)
Java HotSpot(TM) 64-Bit Server VM warning: Sharing is only supported for boot loader classes because bootstrap classpath has been appended
controller <-- 요 부분이 잘 출력되면 됩니다.
service
repository
2025-03-30T15:26:04.010+09:00 INFO 67291 --- [todo-api] [ionShutdownHook] j.LocalContainerEntityManagerFactoryBean : Closing JPA EntityManagerFactory for persistence unit 'default'
2025-03-30T15:26:04.011+09:00 INFO 67291 --- [todo-api] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown initiated...
2025-03-30T15:26:04.012+09:00 INFO 67291 --- [todo-api] [ionShutdownHook] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Shutdown completed.
종료 코드 0(으)로 완료된 프로세스
Shell
복사
@SpringBootTest 를 사용한 테스트라서 이렇게 스프링 부트 로고가 올라와야 정상입니다.
controller, service, repository 객체를 직접 new 해서 생성한 적이 없음에도 controller, service, repository 가 순서대로 출력되면 성공입니다!
마감 기한
4/15 화요일 23:59까지 제출해주세요.
모두 중간고사도 화이팅입니다~!!
자신의 레포지토리에 week2 폴더를 생성해 wil.md 파일을 제출합니다.
더 자세한 사항은 아래 링크를 참조해주세요.