JaPark Bug World

[SpringBoot] 스프링부트3 구조 이해하기 본문

개발새발/스프링부트3 백엔드 개발자 되기

[SpringBoot] 스프링부트3 구조 이해하기

JAstory 2024. 4. 8. 12:56

3.1 스프링부트 3 구조 살펴보기

스프링 부트는 각 계층이 양 옆의 계층과 통신하는 구조를 따른다. (자세한 내용은 교재 79p 참조) 계층이라는 것은 각자의 역할과 책임이 있는 어떤 소프트웨어의 구성 요소를 의미한다. 각 계층은 소통할 수 있지만 다른 계층에 직접 간섭하거나 영향을 미치지 않는다.

 

프레젠테이션 계층 (Controller)

HTTP 요청을 받고 이 요청을 비즈니스 계청으로 전송하는 역할이다. 컨트롤러는 스프링 부트 내에 여러 개가 있을 수 있다.

비즈니스 계층 (Service)

모든 비즈니스 로직을 처리한다. 서비스를 만들기 위한 로직이며, 웹 사이트에서 벌어지는 모든 작업, 발생하는 예외 등 프로세스를 구현하기 위한 로직 등.

퍼시스턴스 계층(Repository)

모든 데이터베이스 관련 로직을 처리한다. 데이터베이스에 접근하는 DAO 객체를 사용할 수 도 있다. DAO는 데이터베이스 계층과 상호작용하기 위한 객체

 

스프링부트 프로젝트 디렉터리 구성하며 살펴보기

 

main

실제 코드를 작성하는 공간이며, 프로젝트 실행에 필요한 소스코드나 리소스 파일이 들어있다.

 

test

프로젝트의 소스 코드를 테스트할 목적의 코드나 리소스 파일이 들어 있다.

 

build.gradle

빌드를 설정하는 파일, 의존성이나 플러그인 설정 등과 같이 빌드에 필요한 설정을 할 때 사용한다.

 

settings.gradle

빌드할 프로젝트의 정보를 설정하는 파일

 

 

build.gradle  의존성 형식

  • implementation
    • 프로젝트 코드가 컴파일 시점과 런타임에 모두 해당 라이브러리를 필요로 할 때 사용
  • testImplementation
    • 프로젝트의 테스트 코드를 컴파일하고 실행할 때만 필요한 의존성을 설정, 테스트 코드에서만 사용, 메인 애플리케이션 코드에서는 사용하지않음.
  • runtimeOnly
    • 런타임에만 필요한 의존성을 지정, 컴파일 시에는 필요하지 않지만, 애플리케이션을 실행할 때 필요한 라이브러리 설정
  • annotationprocessor
    • 컴파일 시에 애너테이션을 처리할 때 사용하는 도구의 의존성 지정 

프레젠테이션 계층

@RestController
public class TestController {
    @Autowired  // TestService 빈 주입
    TestService testService;

    @GetMapping("/test")
    public List<Member> getAllMembers() {
        List<Member> members = testService.getAllMembers();
        return members;
    }
}

 

비즈니스 계층 

@Service
public class TestService {

    @Autowired
    MemberRepository memberRepository;  // 빈 주입

    public List<Member> getAllMembers() {
        return memberRepository.findAll();
    }
}

 

퍼시스던트 계층

@NoArgsConstructor(access = AccessLevel.PROTECTED)
@AllArgsConstructor
@Getter
@Entity
public class Member {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", updatable = false)
    private Long id;        // DB TABLE 'id' column matching

    @Column(name = "name", nullable = false)
    private String name;    // DB TABLE 'name' column matching
}
// member라는 이름의 테이블에 접근해서 Member 클래스에 매핑하는 구현체
public interface MemberRepository extends JpaRepository<Member, Long> {
}

 

작동 확인하기

결과물을 볼 수 있는 데이터가 하나도 입력이 되지 않은 상태이다보니 실행 테스트를 위해 애플리케이션을 실행할 때마다 SQL문을 실행헤 데이터베이스에 직접 데이터를 넣는 과정이 필요하다. 그러나 스프링부트에서는 인메모리 데이터베이스를 사용하고 있기 때문에 애플리케이션을 실행할 때 원하는 데이터를 자동으로 넣는 작업이 존재.

 

resources > data.sql

INSERT INTO member(id, name) VALUES (1, 'name 1')
INSERT INTO member(id, name) VALUES (2, 'name 2')
INSERT INTO member(id, name) VALUES (3, 'name 3')

 

resources > application.yml

# 주의사항: 라인에 따라 게층 구조를 나타내므로 들여쓰기가 일관되어야 한다.
spring:
  jpa:
    # 전송 쿼리 확인
    show-sql: true
    properties:
      hibernate:
        format_sql: true

    # 테이블 생성 후에 data.sql 실행
    defer-datasource-initialization: true

 

show-sql, format_sql 옵션은 애플리케이션 실행 과정에 데이터베이스에 쿼리할 일이 있으면 실행 구문을 보여주는 옵션이고, defer-datasource-initialization 옵션은 애플리케이션을 실행할 때 테이블을 생성하고 data.sql파일에 있는 쿼리를 실행하도록 하는 옵션

 

서버 실행 후 콘솔창에 CREATE TABLE 확인

 

포스트맨으로 Request 요청 후 결과

 

HTTP 요청 (url:/test) -> TestController.java <-> TestService.java <-> MemberRepository.java <-> 데이터베이스

data.sql 에 어떻게 접근이 되서 데이터를 가져오는지 아직 개념이 잘 잡히지 않는다.ㅜㅜ


스프링부트3 백엔드 개발자 되기: 자바 편 책(저자 신선영)을 참고하여 정리한 내용입니다.