DEVELOPMENT/Spring

[스프링부트 완전정복] 3. 스프링 부트의 구조

Tiny Commit 2025. 10. 1. 14:55

 

 

1. 스프링 부트의 프로젝트 구조

1. 프로젝트 구조

  • src/main/java: 클래스, 인터페이스 등의 자바 파일을 저장
  • src/main/resources: 웹관련 폴더(html, css, 자바스크립드, xml, 환경설정파일) templates, static, appication.properties
  • build.gradle: 빌드 정보 정의 파일

2. 메인 파일

  • @SpringBootApplication: 스프링 부트 애플리케이션을 시작할 수 있게 한다.욘ㄱ
  • main(): 애플리테이션의 시작점이자 진입점인 메인 메서드
  • SpringApplication.run(): 웹 애플리케이션을 실행시키는 메서드입니다. 

3. 빌드 정의 파일: build.gradle

  • 플러그인 설정
  • 자바버전
  • 필요한 라이브러리 자동 젖아
  • 의존성 주입

 

 

2. 스프링 부트의 계층적 구조

1. 계층적 구조

  • 연결 관계가 긴밀한 부분끼리 묶어서 특정 기술이나 인터페이스로부터 분리시키는 방법
  • 관심사를 분리하고 느슨하게 결합하여 계층 간의 유연하게 동작하도록함.
    • 퍼시스턴스 계층: 데이터 베이스 처리
    • 비즈니스 계층: 포괄적인 서비스
    • 프레젠테이션 계층: 사용자와의 접점, 데이터 입력이나 결과를 웹서버에 전달. 
    • 도메인 객체: 데이터 모델로, 객체 정보를 저장합니다.

2. 계층적 구조의 구현

 

3. [도서 쇼핑몰] 계층적 구조 만들기

1. 쇼핑몰의 계층적 구조

  • 계층 구조

  • 계층 구조 적용 과정

 

 

2. 도서 기본 정보가 담신 도메인 객체

  • 도메인 객체: 다른 계층의 토대가 되는 데이터 객체입니다.
  • 주문 고객 정보, 배송 주소, 주문 항목 등
  • 도메인 객체는 데이터 모델이므로 Setter(), Getter() 사용 (lombok)
  • 생성방법
    • src/main/java.domain/ → 클래스 생성 (Book.java)
    • 멤버 변수 선언
    • 기본 생성자 추가
    • 모든 변수의 Setter(), Getter() 매서드 추가
package com.springboot.domain;

import java.math.BigDecimal;

public class Book {
    private String bookId;        // 도서 ID
    private String name;          // 도서 제목
    private BigDecimal unitPrice; // 가격
    private String author;        // 저자
    private String description;   // 설명
    private String publisher;     // 출판사
    private String category;      // 분류
    private long unitsInStock;    // 재고수
    private String releaseDate;   // 출판일(월/년)
    private String condition;     // 신규도서 or 중고도서 or 전자책

    public Book() {
        super();
    }

    public String getBookId() {
        return bookId;
    }
    public void setBookId(String bookId) {
        this.bookId = bookId;
    }

    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    public BigDecimal getUnitPrice() {
        return unitPrice;
    }
    public void setUnitPrice(BigDecimal unitPrice) {
        this.unitPrice = unitPrice;
    }

    public String getAuthor() {
        return author;
    }
    public void setAuthor(String author) {
        this.author = author;
    }

    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }

    public String getPublisher() {
        return publisher;
    }
    public void setPublisher(String publisher) {
        this.publisher = publisher;
    }

    public String getCategory() {
        return category;
    }
    public void setCategory(String category) {
        this.category = category;
    }

    public long getUnitsInStock() {
        return unitsInStock;
    }
    public void setUnitsInStock(long unitsInStock) {
        this.unitsInStock = unitsInStock;
    }

    public String getReleaseDate() {
        return releaseDate;
    }
    public void setReleaseDate(String releaseDate) {
        this.releaseDate = releaseDate;
    }

    public String getCondition() {
        return condition;
    }
    public void setCondition(String condition) {
        this.condition = condition;
    }
}

 

 

 

 

3. 도서 정보를 관리하는 퍼시스턴스 계층

  • 퍼시스턴스 객층: 도메인 객체에 접근할 수 있는 저장소 객체
  • @Repogiroty: 해당 클래스가 저장소 객체임을 나타낸다.
  • 저장소 객체 생성하기
    • 인터페이스 생성: BookRepository.java
    • 매서드 선언
    • 클래스 생성: BookRepositoylmpl.java
    • 멤버변수와 기본 생성자 작성
    • 메서드 추가
// BookRepository.java
package com.springboot.repository;

import java.util.List;
import com.springboot.domain.Book;

public interface BookRepository {
    List<Book> getAllBookList();
}

 

// BookRepositoryImpl.java
package com.springboot.repository;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

import org.springframework.stereotype.Repository;
import com.springboot.domain.Book;

@Repository
class BookRepositoryImpl implements BookRepository {

    private List<Book> listOfBooks = new ArrayList<Book>();

    public BookRepositoryImpl() {
        Book book1 = new Book();
        book1.setBookId("ISBN1234");
        book1.setName("자바스크립트 입문");
        book1.setUnitPrice(new BigDecimal(30000));
        book1.setAuthor("조현영");
        book1.setDescription("자바스크립트의 기초부터 심화까지 핵심 문법을 학습한 후 12가지 프로그램을 만들며 학습한 내용을 확인할 수 있습니다. 문법 학습과 실습이 적절히 섞여 있어 프로그램을 만드는 방법을 재미있게 익힐 수 있습니다.");
        book1.setPublisher("길벗");
        book1.setCategory("IT전문서");
        book1.setUnitsInStock(1000);
        book1.setReleaseDate("2024/02/20");

        Book book2 = new Book();
        book2.setBookId("ISBN1235");
        book2.setName("파이썬의 정석");
        book2.setUnitPrice(new BigDecimal(29800));
        book2.setAuthor("조용묵, 임찬수");
        book2.setDescription("4차 산업혁명의 핵심인 머신러닝, 사물 인터넷(IoT), 데이터 분석 등 다양한 분야에 활용되는 직관적이고 간결한 문법의 파이썬 프로그래밍 언어를 최신 트렌드에 맞게 예제 중심으로 학습할 수 있습니다.");
        book2.setPublisher("길벗");
        book2.setCategory("IT교육교재");
        book2.setUnitsInStock(1000);
        book2.setReleaseDate("2023/01/10");

        Book book3 = new Book();
        book3.setBookId("ISBN1236");
        book3.setName("안드로이드 프로그래밍");
        book3.setUnitPrice(new BigDecimal(36000));
        book3.setAuthor("송미영");
        book3.setDescription("안드로이드의 기본 개념을 체계적으로 익히고, 이를 실습 예제를 통해 익힙니다. 기본 개념과 사용법을 스스로 실전에 적용하는 방법을 학습한 다음 실습 예제와 응용 예제를 통해 실전 프로젝트 응용력을 키웁니다.");
        book3.setPublisher("길벗");
        book3.setCategory("IT교육교재");
        book3.setUnitsInStock(1000);
        book3.setReleaseDate("2023/06/30");

        listOfBooks.add(book1);
        listOfBooks.add(book2);
        listOfBooks.add(book3);
    }

    @Override
    public List<Book> getAllBookList() {
        return listOfBooks;
    }
}

 

 

4. 요청한 도서 목록을 반환하는 비즈니스 계층

  • 비즈니스 계층
  • @Service: 서비스 객체임을 선언
  • 생성하기
    • 인터페이스 생성: BookServeice.java
    • 메서드 작성
    • 클래스 생성: BookServiceImpl.java
    • 메서드 작성
// BookServeice.java
package com.springboot.service;

import java.util.List;
import com.springboot.domain.Book;

public interface BookService {
    List<Book> getAllBookList();
}

 

// BookServiceImpl.java
package com.springboot.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.springboot.domain.Book;
import com.springboot.repository.BookRepository;

@Service
public class BookServiceImpl implements BookService {

    @Autowired
    private BookRepository bookRepository;

    @Override
    public List<Book> getAllBookList() {
        return bookRepository.getAllBookList();
    }
}

 

 

 

5. MVC를 담당하는 프레젠테이션 객층

  • 프레젠테이션 객층: 웹 브라우저로 들어오는 요청을 처리하고 결과를 웹에 표현
  • 컨트롤러(@Controller): 웹에 들어오는 요청 처리
  • 뷰(타임리프 템플릿 엔진적용): 결과를 웹에 보여줌
  • 모델: 웹 페이지에 출력할 데이터
  • 생성하기
    • 컨트롤러: 클래스 생성, 메서드 작성: BookController.java
    • 뷰 구현: 웹페이지 생성, 출력 코드 작성 : books.html
// BookController.java
package com.springboot.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import com.springboot.domain.Book;
import com.springboot.service.BookService;

@Controller
public class BookController {

    @Autowired
    private BookService bookService;

    @RequestMapping(value = "/books", method = RequestMethod.GET)
    public String requestBookList(Model model) {
        List<Book> list = bookService.getAllBookList();
        model.addAttribute("bookList", list);
        return "books";  // → templates/books.html로 매핑됨
    }
}

 

 

6. 의존 라이브러리 설정하기

  • 의존 라이브러리 추가
  • 의존 라이브러리 설정
  • 의존 라이브러리 갱신
dependencies {
    implementation 'org.springframework.boot:spring-boot-starter'
	implementation 'org.springframework.boot:spring-boot-starter-thymeleaf'
	implementation 'org.springframework.boot:spring-boot-starter-web'
	compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
	testRuntimeOnly 'org.junit.platform:junit-platform-launcher'
}

 

7. 실행결과 확인

  • 실행: http://localhost:8080/books
  • 결과 확인

왜 이런식으로 나오지..ㅜ

 

8. 프로젝트 실행 경로 변경하기

  • 원래: http://localhost:8080/books
  • 갱신할 URL: http://localhost:8080/BookMarket/books 
    • 경로 설정: application.properties: 
pspring.application.name=Book
server.servlet.context-path=/Book

 

 

 

 

 

 


 

 


연습문제

01. HTML, JSP 동적 파일 매핑 경로

  • 정답: ③ src/main/resources/templates
  • 이유: 템플릿 엔진(JSP, Thymeleaf 등) 파일은 templates에 둠.

02. JS, CSS 정적 리소스 매핑 경로

  • 정답: ② src/main/resources/static
  • 이유: 정적 리소스(JS, CSS, 이미지)는 static에 둠.

03. @SpringBootApplication에 포함되지 않는 애너테이션

  • 정답: ④ @EnableConfiguration
  • 이유: 실제 구성요소는 @EnableAutoConfiguration, @ComponentScan, @Configuration.

04. 기본 외존 라이브러리 아님

  • 정답: ④ spring-boot-starter-thymeleaf
  • 이유: 웹 애플리케이션 필수 기본은 web, jpa, security. Thymeleaf는 선택적 템플릿 엔진.

05. 계층 설명 틀린 것

  • 정답: ① 도메인 계층 설명
  • 이유: 도메인 계층은 "객체 저장"이 아니라 비즈니스 도메인의 핵심 개념(엔티티, VO 등) 을 표현.

06. 프레젠테이션 계층에 해당하지 않는 것

  • 정답: ① 데이터베이스
  • 이유: DB는 퍼시스턴스 계층에 해당.

07. 저장소 객체 애너테이션

  • 정답: ② @Repository
  • 이유: 영속성 계층(저장소)을 나타내는 전용 애너테이션.

08. 프레젠테이션 ↔ 퍼시스턴스 계층 연결 애너테이션

  • 정답: ① @Controller
  • 이유: Controller가 사용자 요청을 받아 서비스/DAO와 연결.

09. 자바 클래스가 컨트롤러임을 알려주는 애너테이션

  • 정답: ① @Controller
  • 이유: 스프링 MVC 컨트롤러 지정용.

10. 실행 경로 변경 (application.properties 설정)

  • 정답: ② server.servlet.context-path=/Exercise
  • 이유: context path 변경은 server.servlet.context-path 사용.

 

 

 


 


출처 : 송미영, 『 스프링부트 완전정복: 개념부터 실정 프로젝트까지 』길벗캠퍼스 (2024).