[인프런 워밍업 클럽 스터디]BE 1기 두번째 발자국
저번주에 호기롭게 다짐했던 이번주에는 공부를 미리 다해보자!라고 했는데
오히려 저번주보다 공부를 덜 했다...
분명 할 시간이 많을거라 생각했는데 이것저것 해보던 취준과 여행의 여파로 너무 피곤하기만 해서 뭘 제대로 해보지도 못하고 한 주가 지나갔다.
열심히 해보려던 과제도 결국 두 개 중 하나만 제출하고 너무 허무한 한 주이다.
그래서 그런지 더욱 머리에 내용이 안 남지만,, 낼부터는 진짜 열심히 해야겠다고 다시 한 번 다짐한다!!
이번주에는 나름의 복습으로 저번주에 공부하면서 정리했던 내용들을 다시 읽어보았다.
사실 자바도 익숙하지 않아서 스프링은 더 안 낯선 언어인데 그래도 한 번 쓰면서 공부해봤다고 조금 눈에 익은 것 같다.
섹션3 밖에 다 하지 못 했지만 다음주에는 얼른 진도에 맞춰 끝내놔야겠다.
Section3
역할의 분리와 스프링 컨테이너라는 제목이다.
역할의 분리가 얼마나 중요할까?에 대해서 생각하면서 코드를 짜본적은 없던 것 같다. 아무래도 급하게 프로젝트만 하니 아 그냥 분리하는게 좋구나 해서 분리했던 기억이 난다.
Layered Architecture
3단 분리를 해야하는 이유?!
💡 Controller에서 모든 기능을 구현하면 왜 안 될까?
=> 함수는 최대한 작게 만들고 한 가지 일만 수행하는 것이 좋다고 설명해주셨다. 클래스는 작아야 하며 하나의 책임만을 가져야 한다.
예를 들어, 만약 controller 함수 1개가 3000줄이 넘으면?
그 함수를 동시에 여러 명이 수정할 수 없음
그 함수를 읽고, 이해하는 것이 너무 어려움
그 함수의 어느 부분을 수정하더라도 함수 전체에 영향을 미칠 수 있기 때문에 함부로 건들 수 없게 됨
너무 큰 기능이기 때문에 테스트도 힘듦
종합적으로 유지보수성이 매우 떨어짐
결국 이런 이유로 Controller에 모든 기능을 넣기 보다는 Service와 Repository에 나누는 게 좋다!!
여태 작성했던 코드는
API의 진입 지점으로써 HTTP Body를 객체로 반환
현재 유저가 있는지 없는지 확인하고 예외 처리함
SQL을 사용해 실제 Database와의 통신을 담당
를 Controller에서 모두 하고 있었는데 1번은 Controller, 2번은 Service, 3번은 Repoitory로 나누는 작업을 한다.
3가지 역할을 나누는 것을 Layered Architecture 라고 하는데
Controller ← Service ← Repository (DTO는 계층 간의 정보 전달 역할) 로 나눠진다.
이 때 기능만 나눠서는 안 된다. 우리는 JdbcTemplate
를 파라미터로 계속 받고 있어 오류가 생긴다.
해결 방법은 UserRepository
도 Usercontroller
처럼 JdbcTemplate
를 변수로 받으면 된다.
그럼 또 다음과 같은 의문점이 생긴다
💡Controller에 있는 JdbcTemplate 는 어디서 온 걸까? → Repository에서 바로 JdbcTemplate를 가져올 수는 없을까?
답은 @RestController
이다.
@RestController
어노테이션을 사용하면 UserController 클래스를 API의 진입 지점으로 만들 뿐 아니라 UserController 클래스를 스프링 빈으로 등록시키는 역할을 해준다.
스프링빈이란?
서버가 시작되면, 스프링 서버 내부에 거대한 컨테이너를 만들고, 컨테이너 안에는 클래스가 들어가게 됨
⇒ 이 때 다양한 정보도 함께 들어있고, 인스턴스화도 이루어짐
즉, 이때 스프링 컨테이너 안으로 들어간 클래스를 스프링 빈이라고 한다.
JdbcTemplate
도 이미 스프링 빈으로 등록되어 있음
JdbcTemplate
은 우리가 build.gradle에서 설정한 dependency(의존성)에서 등록해주고 있었다!
스프링 컨테이너는 필요한 클래스를 연결해준다
서버가 시작되면 다음과 같은 일이 일어나는데
스프링 컨테이너(클래스 저장소)가 시작
기본적으로 많은 스프링 빈들이 등록됨(JdbcTemplate)
우리가 설정해준 스프링 빈 등록(UserController)
이때 필요한 의존성이 자동으로 설정됨
💡 그렇다면 왜 UserRepository
는 JdbcTemplate
을 가져오지 못할까?
⇒ JdbcTemplate
을 바로 가져오려면 스프링 빈이어야 하는데 UserRepository
는 스프링 빈이 아니다
⇒ UserRepository
를 스프링 빈으로 등록해보자!!
여기서 Repostitory에는 @Repostitory
Service에는 @Service
를 각각 등록해주면 스프링 빈으로 등록된 것이다.
💡 좋아진 것 같긴 한데 왜 스프링 컨테이너를 사용하지? 그냥 new 연산자 쓰면 되는거 아닝가?? 라는 의문이 들 것이다.
책을 저장하는 api를 만든다고 가정해보자.
그럼 Controller, Service, Repository 이렇게 구성하고 만들 것이다.
이 때 db를 메모리에만 저장하는 코드로 구성했다가, MySql과 같은 db에 저장한다고 하면
repository가 수정될 때마다 새로 new BookMySqlRepository();
이런 식으로 계속 추가해야 한다.
자동으로 연결해주기 위해 스프링 컨테이너를 활용한다!
스프링 컨테이너란 컨테이너가 BookService를 대신 인스턴스화 하고 그 때 알아서 BookRepository를 결정해주는 건데 BookService
와 BookRepository
가 모두 스프링 빈이라면 스프링 컨테이너는 BookService
를 알아서 인스턴스화 하고BookRepository
를 결정해줄 것이다.
BookRepository
package com.group.libraryapp.repository.book;
import org.springframework.stereotype.Repository;
@Repository
public class BookMySqlRepository implements BookRepository{
@Override
public void saveBook() {
}
}
BookController
public class BookController {
// 2. BookService 연결 => 스프링 빈이 아닌 경우
private final BookService bookService; // instance화 할 필요 X
public BookController(BookService bookService) {
this.bookService = bookService;
} // 생성자 추가(constructor)
이렇게 하면 알아서 어떤 레포지토리를 불러올지 결정한다.
이때 레포지토리가 너무 많다면 @Primary
를 사용해 어떤 레포지토리를 우선순위에 둘지 레포지토리에 직접 설정해준다.
빈을 사용하는 방법
@Configuration
와 @Bean
이 있는데 둘은 항상 같이 사용해야 한다.
@Configuration
class에 붙이는 어노테이션
@Bean
을 사용할 때 함께 사용해 주어야 함
@Bean
method에 붙이는 어노테이션
메소드에 반환되는 개체를 스프링 빈에 등록
@Configuration
이라는 어노테이션은 보통 config
라는 패키지에 만든다.
@Component
주어진 클래스를
컴포넌트
로 간주컴포넌트로 간주된 클래스들은 스프링 서버가 뜰 때 자동으로 감지된다.
@RestController
,@Service
,@Repository
,@Configuration
어노테이션은 모두@Component
어노테이션을 가지고 있음
스프링 빈을 주입 받는 방법
생성자를 이용해 주입받는 방식 (가장 권장)
setter
를 통해 주입받는 방식필드에 직접 주입하는 방법
권장 X
setter
를 통해 다른 인스턴스로 교체해 동작에 문제가 생길 수 있음필드에 바로 주입하게 되면 테스트가 어려움
과제5
클린 코드에 대해 배우고 클린 코드 직접 작성하기
https://velog.io/@dmsqls19/인프런-워밍업-클럽-1기-BE-과제5.-클린-코드Clean-Code
느낀 점
일단 이번주에 공부를 너무 안 해서,,, 조금 회고록이 짧은 것에 대해 반성해야겠다.
그리고 배우면서 느낀건 클린코드가 정말 중요하다는 걸 깨달았다.
내가 쓴 코드에 대해 설명할 때 이건 왜 이렇게 구성했는지에 잘 파악하면 된다고 생각했는데 줄일 수 있는 건 최대한 줄이면서 간결하게 하는 것도 중요하다는 걸 느꼈다. 코드가 왜이렇게 복잡하지? 했던 것도 다 줄일 수 있는 것들이었다.
배운 것보다 배울 게 더 많다 라는 생각과 함께 걱정은 되지만 새로운 걸 배우는 건 늘 재밌기 때문에 다음주도 기대가 된다.
댓글을 작성해보세요.