스프링부트로 웹 페이지 만들어보기

저번에 만들던거에 이어서 DB 연결과 글 작성 기능 백엔드, 글 목록 기능까지 기록해보겠습니다.

DB 연결의 경우 일단 완성이 목표이기에 계정 관련을 하드코딩하여 만든 후 서버로 옮겨서 서비스 해볼때 설정을 마무리 해볼 생각입니다.

 

1. DB 연결

DB는 MySQL을 사용했습니다. 버전은 8.2입니다.

//application.yml
server:
  port: 8080

spring:
  application:
    name: demo
  datasource:
    driver-class-name: com.mysql.cj.jdbc.Driver
    url: jdbc:mysql://localhost:3306/db_first?serverTimezone=Asia/Seoul&characterEncoding=UTF-8
    username: hyj562
    password: 1234
  thymeleaf:
    cache: false

  jpa:
    open-in-view: false
    show-sql: true
    hibernate:
      ddl-auto: update
      format_sql: true

 

DB 접속용 파일입니다.

일단은 클라이언튼에서 시험용으로 사용할거기에 계정정보도 하드코딩하여 DB와 연결해주었습니다.

 

JPA란 자바 객체와 DB 테이블을 매핑하기 위한 방식 중 하나입니다.

후에 DB 테이블을 만들 SQL이 아닌 자바로 작성하게 해줍니다.

 

JPA를 사용하기 위해 build.gradle에는 아래와 같이 추가해주었습니다.

dependencies {
    //생략...
	implementation 'org.springframework.boot:spring-boot-starter-data-jpa'
	runtimeOnly 'com.mysql:mysql-connector-j'
}

 

이후 MySQL 워크벤치에서 SQL구문으로 db_first라는 데이터베이스를 만들어주었습니다.

 

2. 스프링부트의 전체 구조

앞선 글에서 글 작성 기능을 폼을 통해서 만들었습니다.

하지만 스프링부트의 전체 구조를 재대로 파악하지 못 했다보니, 서비스나 엔티티를 만들어야한다곤 하는데..
왜, 어떻게 만들어야하는지가 재대로 학습되지 못 했습니다.

때문에 이번엔 시간을 가지고 스프링부트의 구조와 최근 스프링부트 개발에서 가장 권장되는 방식인 생성자 주입 방식에 대해서 더 자세히 알아가보고자 합니다.

 

스프링부트의 구조를 공부하다보니, 역할이 명확히 분리된 구조를 가진다는걸 알게되었습니다.

 

사용자 (브라우저)
     ↓ 요청 (HTTP)
Controller       ← 사용자의 요청을 받는 부분
     ↓
Service          ← 핵심 로직
     ↓
Repository       ← DB와 직접 통신, 데이터를 저장하고 조회
     ↓
Entity           ← DB 테이블과 1:1로 매핑된 자바 객체, 실제 데이터 구조

 

위와 같은 단계로 서비스가 작동 한다는걸 알았습니다.

저는 지금 컨트롤러 부분까지 만들었으니, 글을 작성하는 핵심 로직인 서비스와, 그걸 저장하고 그 저장하는 공간을 만드는 레파지토리와 엔티티를 작성할 차례라는걸 알 수 있었습니다.

3. 생성자 주입 방식이란

생성자 주입 방식이란 스프링부트에서 의존성을 주입하는 3가지의 방식 중 하나입니다.

이에 대해서 더 자세히 이해할려면 의존성 주입에 관하여 공부를 해야겠네요.

 

의존성(Dependency)이란, 어떤 객체가 다른 객체를 필요로 하는 관계를 뜻합니다.

public class BoardService {
    private BoardRepository boardRepository;

    public void savePost() {
        boardRepository.save(); // BoardRepository가 필요함
    }
}

 

위의 BoardService를 보면 savePost() 에서 BoardRepository의 save() 메서드를 호출하고있습니다.

즉 BoardService가 재대로 동작하려면 BoardRepository에서 메서드를 가져불러와야 합니다.

이러한 관계를 BoardService가 BoardRepository에 의존한다 라고 말 합니다.

 

그럼 의존성 주입(Dependency Injection, DI)는 말 그대로 의존성을 넣어주는겁니다. 이때 우리가 직접 만드는게 아닌 스프링이 넣어주는 방식인거죠.

원래는..

public class BoardService {
    private BoardRepository boardRepository = new BoardRepository();
}

 

이러한 방식으로 BoardService안에 BoardRepository에 관하여 선언을 해줘야했습니다.

제가 학교에서 자바시간에 배울때도 이렇게 작성했었네요.

하지만 요즘에는 유지보수와 테스트 등 여러방면에서 불편하여 이러한 방식을 사용하지 않는다고합니다.

스프링이 여러 어노테이션을 보고 자동으로 의존성 주입을 해주며 그러한 방식을 선호한다네요.

스프링의 IoC 컨테이너(Bean Container)가 이를 담당한답니다. 

다음에 더 자세히 알아봐야겠네요.

 

생성자 주입은 이러한 스프링의 자동 의존성 주입의 방법 중 하나입니다.

@Service
@RequiredArgsConstructor // lombok이 final 필드 기반으로 생성자 자동 생성
public class BoardService {

    private final BoardRepository boardRepository;  // 의존성

    public void save(Board board) {
        boardRepository.save(board);
    }
}

 

@Service 어노테이션을 통하여 이 클래스가 서비스 역할을 한다는것을 스프링에알리면,

Lombok에 포함된 @RequiredArgsConstructor 어노테이션이 final 필드를 기반으로 생성자를 만들어줍니다.

이후 스프링이 BoardRepository를 자동으로 찾아서 넣어주는 식으로 동작합니다.

이런 방식을 통해 개발자가 직접 new를 쓰는 수고를 덜 할 수 있습니다.

 

오늘 공부한걸 통해서 글쓰기 서비스의 백엔드 부분을 마무리하고 더 다양한 기능들을 추가 해보겠습니다.

 

+ Recent posts