스프링 입문 - 코드로 배우는 스프링 부트, 웹 MVC, DB 접근 기술
본 내용은 김영한님의 인프런 강의 중 글 제목의 강의를 보고 정리한 글입니다. (정리까지는 아니고 메모?)
gradle은 의존관계가 있는 라이브러리를 함께 다운로드 한다.
+빌드, 라이브러리관리
아래 캡쳐화면을 보면 스프링 이니셜라이져를 통해 프로젝트를 생성할 때, thymeleaf와 web 라이브러리만 추가해서 생성했지만 라이브러리 의존 관계를 보면 여러 라이브러리가 연결되어있고 gradle이 의존관계가 있는 모든 라이브러리들을 같이 가져와주는 것을 알 수 있다.
스프링 부트 라이브러리
- spring-boot-starter-web
- spring-boot-starter-tomcat
- spring-webmvc: 스프링 웹 MVC
- spring-boot-starter(공통): 스프링부트 + 스프링 코어 + 로깅
- spring-boot
- spring-core
- spring-boot-starter-logging
- logback, slf4j
- spring-boot
- spring-boot-starter-test
- junit : 테스트 프레임워크
- mockito : mock 라이브러리
- assertj
- spring-test : 스프링 통합 테스트 지원
View
thymeleaf 사용.
controller에서 html 파일명을 문자열로 반환하면 뷰 리졸버(viewResolver)가 화면을 찾아서 처리한다.
- 문자열 앞 뒤에 resource:templates/ 와 .html을 추가 후 매핑.
Build
인텔리제이에서가 아닌 로컬에서 실행해보기.
- ./gradlew build로 프로젝트의 jar 파일 생성( ./build/libs/ )
- java -jar {파일명}을 하면 실행
- ./gradlew clean 으로 build 파일 제거
스프링 웹 개발 기초
- 정적 컨텐츠
- 스프링 부트는 정적 컨텐츠 제공 기능(web server)을 제공한다.
- /resources/static 폴더에 정적 컨텐츠를 만들면 서버에서 전달해줌.
- 어떤 프로그래밍을 할 수는 없다. 그대로 반환한다.
- MVC와 템플릿 엔진
- 과거에는 JSP로 view, 디비접근, 로직 처리를 모두 한곳에서 처리하기도 함.
- MVC 패턴은 관심사를 분리하는 것.
- ViewResolver가 경로를 붙이고 html페이지를 찾고, html로 변환을 시켜서 반환.
- API
- ViewResolver 대신 JsonConverter, SpringConverter가 동작.
실습
- 컨트롤러 : 웹 MVC의 컨트롤러 역할
- 서비스 : 핵심 비지니스 로직 구현
- 레포지토리 : 데이터베이스 접근, 도메인 객체를 DB에 저장하고 관리
- 도메인 : 비즈니스 도메인 객체
repository는 DB를 다루는 목적의 의미.
- 예를들어 조회, 생성, 수정, 삭제.
service의 메소드는 좀 더 비즈니스적인 의미.
- 회원가입, 전체 회원 조회 등등
- 따라서 service의 메소드 명은 좀 더 비즈니스적인 네이밍을 해줘야 좋다. 그래야 이 후에 코드를 찾아 들어갈 때 편리.
DI (Dependency Injection)
- 외부에서 의존성을 주입해준다.
- 쉽게 얘기하면 외부에서 객체를 생성해서 넣어준다.
- 예제에서는 한 객체에서 사용되는 객체가 외부의 다른 객체에서 동일하게 사용될 때, DI를 해주지 않으면 외부에서 사용되는 객체와 외부에서 사용하는 객체 내부의 객체가 동일한 것임에도 불구하고 따로 생성이 됨. 외부에서 어차피 객체를 사용하기 때문에 생성하고 동일한 객체를 사용하는 객체에 대해서는 생성자를 통해 객체를 넣어줌.
DI 방법
- 필드 주입
- 세터 주입
- 생성자 주입 (권장)
의존관계
- @Component으로 해당 클래스 객체를 스프링 컨테이너에서 관리하도록 하고, 생성자에 @Autowired를 달아주면 해당 클래스의 객체가 생성될 때 해당 생성자로 객체를 넣어준다(생성해주는 대신에).(DI) → 해당 객체를 여러 클래스에서 사용하면 굳이 그 때 그 때 만들어줄 필요없이 동일한 객체를 사용하게 됨.
빈 등록 방법
컴포넌트 스캔
→ 위의 의존관계에서 말한 @Component 어노테이션을 사용하는 것.
자바 코드로 직접 빈등록
H2 설치하고 웹콘솔로 실행시켜보기
- 영한님은 DB 구축하거나 할 때 사용한 쿼리문들을 프로젝트에 따로 폴더를 하나 만들어 관리한다.
- django의 migrate 폴더와 같이 DB현재 상태 파악 및 이력 관리 느낌으로 사용하시는 듯.
순수 JDBC를 이용해서 프로젝트와 DB를 연결해보기
- JDBC와 h2 의존성 주입 및 라이브러리 설치.
implementation 'org.springframework.boot:spring-boot-starter-jdbc'
runtimeOnly 'com.h2database:h2'
- 객체지향의 다형성을 이용해서 MemberRepository를 구현한 다른 Repository를 만들어주고, Config에 객체만 해당 객체로 수정하면 다른 수정이 필요없게 된다. SOLID의 개방-폐쇄원칙에도 부합하게 구현
JDBC를 적용한 DB 접근 로직과 관련한 테스트 코드 작성하기.
- Test코드에서 빈주입은 가장 편한 방법, 보통 필드주입을 사용한다. 맨 끝단이며 테스트 코드에서 주입한 빈들이 다른데서 사용되거나 하는 것이 아니기 때문에.
- @SpringBootTest : 스프링 컨테이너와 테스트를 함께 실행한다.
- @Transactional : 테스트 케이스에 이 애노테이션이 있으면, 테스트 시작 전에 트랜잭션을 시작하고, 테스트 완료 후에 항상 롤백한다. 이렇게 하면 DB에 데이터가 남지 않으므로 다음 테스트에 영향을 주지 않는다.
- 단위 테스트와 통합 테스트. 순수한 단위 테스트가 훨씬 더 좋은 테스트일 확률이 높다.(스프링 컨테이너를 띄우지 않고 테스트)
Spring JDBC Template 사용해보기.
- 라이브러리는 순수 JDBC를 사용해볼 때와 그대로.
- JDBC에서 반복되는 코드들을 많이 제거해줌. SQL문은 똑같이 작성 필요.
- JDBC Template은 실무에서도 많이 씀.
JPA(Hibernate) 사용해보기
- SQL문 조차 작성안해도 된다!
Spring Data JPA 사용해보기
- 인터페이스만 만들면 된다!!
- 스프링 Data JPA가 해당 인터페이스를 보고 구현체를 자동으로 만들어서 빈 등록해주기 때문.
- 동적 쿼리에는 제한이 있기에 동적 쿼리 사용시 Query DSL 많이 사용.
AOP
- 관점 지향 프로그래밍 - 기능을 중심으로 바라보고 공통 관심 사항들은 별도로 분리하는 것.
- 공통 관심 사항과 핵심 관심 사항을 분리.