플레이데이터 - 36일차 Spring Boot Framework(1)

Kim Hyen Su·2023년 8월 21일

🌟스프링 부트란?

✅스프링 프레임워크

  • 자바에서 가장 많이 사용되는 프레임워크.
  • 현재 우리나라의 '전자정부 표준 프레임워크'의 기반 기술로 채택.
  • 애플리케이션 개발에 필요한 기반을 제공하여 개발자가 비지니스 로직 구현에만 집중할 수 있게끔 해준다.

1. 제어의 역전(IoC)

  • 기존의 개발자가 객체를 직접 생성하고 관리하던 방식이 아닌, 사용할 객체를 직접 생성하지 않고 객체의 생명주기 관리를 스프링 컨테이너(IoC 컨테이너)에 위임하는 것.
  • 객체의 관리를 컨테이너에 맡겨 제어권이 넘어간 것을 제어의 역전 이라고 하며, 이로 인해 DI 및 AOP가 가능해진다.

2. 의존성 주입(DI)

  • 사용할 객체를 직접 생성하지 않고 외부 컨테이너가 생성한 객체를 주입받아 사용하는 방식.
  • 예를 들어, 하나의 객체에서 사용할 기능 로직을 다른 클래스에 구현한 뒤 해당 클래스 객체를 주입 받아 사용하는 것을 말한다.
  • 이러한 경우를 하나의 객체가 다른 객체에 의존하고 있다고 한다.

의존성 주입 방법 3가지

  1. 생성자를 통한 의존성 주입
  2. 필드 객체 선언을 통한 의존성 주입
  3. setter 메서드를 통한 의존성 주입

3. 관점 지향 프로그래밍(AOP)

  • AOP는 OOP를 더욱 잘 사용하도록 돕기 위한 개념.
  • AOP는 관점 지향 프로그래밍의 약어로써, 관점 이란 어떤 기능을 구현할 때 그 기능의 핵심 기능부가 기능으로 구분하여 각각을 하나의 관점으로 보는 것을 의미한다.
  • 일반적으로 핵심 기능은 사용자 관점에서 필요한 기능이며, 부가 기능은 서버 개발자 관점에서 필요한 기능이다.
  • AOP 방식으로 프로그래밍 하면, 공통되는 부가 기능을 별도로 구현함으로써 핵심 기능 구현 시 부가 기능을 반복하는 코드가 줄어들고, 한곳에 구현된 부가 기능 코드만 수정해도 적용되는 로직이 수정되기 때문에 유지보수가 편하다.
  • 즉, 여러 비지니스 로직에서 반복되는 부가 기능을 하나의 공통 로직으로 처리하도록 모듈화하여 삽입해놓은 방식을 AOP라고 한다.
  • SpringFramework에서는 프록시 패턴을 이용하여 AOP 기능을 제공한다.

✅스프링 프레임워크 VS 스프링 부트

  • 스프링 부트를 이용하면 단독으로 실행 가능한 사용 수준의 스프링 기반 애플리케이션을 손쉽게 만들 수 있다.

1. 의존성 관리

  • 스프링 프레임워크에서는 개발에 필요한 각 모듈의 의존성을 직접 설정해야 했지만, 스프링 부트에서는 spring-boot-starter라는 의존성을 제공하며, 이를 통해 각 라이브러리의 기능과 관련해서 자주 사용되고 서로 호환되는 버전의 모듈 조합을 제공한다. 이를 통해 개발자는 라이브러리 호환 문제 해결이 가능하다.

spring-boot-starter

  • spring-boot-starter-web : 스프링 MVC를 사용하는 RESTful 애플리케이션 개발을 위한 의존성. 기본적으로 톰캣이 내장되어 있어 jar 형식으로 실행이 가능하다.

  • spring-boot-starter-test : JUnit,Hupiter,Mockito 등의 테스트용 라이브러리를 포함.

  • spring-boot-starter-jdbc : HikariCP 커넥션 풀을 활용한 JDBC 긴응을 제공.

  • spring-boot-starter-security : 스프링 시큐리티(인증, 인가 등) 기능을 제공.

  • spring-boot-starter-data-jpa : 하이버네이트를 활용한 spring data JPA를 제공.

  • spring-boot-starter-cache : 스프링 프레임워크의 캐시 기능을 지원.

🌟개발 환경 구성

  • Windows 11 64bits
  • 인텔리제이 Ultimate
  • JDK 11(1.8 버전 이상)
  • 스프링 부트 2.5.6 ~ 2.5.8
  • MySQL DB
  • Maven

🌟스프링 부트 - 애플리케이션 개발

✅프로젝트 생성

  • [File][Project...][Spring Initializr]
    • Name : 프로젝트명 설정
    • Location : 프로젝트 생성 위치 설정
    • Language : JVM 상에서 동작하는 언어 선택.
    • Type : 빌드 툴.
    • Group : 고유한 식별자 정보인 그룹 설정.
    • Artifact : 세부 프로젝트를 식별하는 정보.
    • Pacakge name : Group과 Artifact 입력 시, 자동 입력.
    • Java : 자바 버전 설정.
    • Packaging : 애플리케이션을 쉽게 배포하고 동작하게 할 파일들의 패키징 옵션.

Jar 와 War

모두 자바 언어의 툴에서 사용하는 아카이브 파일. 애플리케이션의 배포와 동작을 위해 사용되는데, 두 형식의 차이점과 특징을 알아두면 좋다.

  • JAR(Java Archive)
    • .jar 확장자 파일에는 Class와 같은 Java 리소스와 속성 파일, 라이브러리 등이 포함되어 있다.
    • 쉽게 자바 애플리케이션이 동작할 수 있도록 자바 프로젝트를 압축한 파일로 생각하면 된다.
    • 실제 JAR 파일은 플랫폼에서 귀속되는 점만 제외하면 ZIP파일과 동일한 구조이다.
    • JRE만 가지고도 실행이 가능하다.
  • WAR(Web Application Archive)
    • .war 확장자 파일은 servlet/jsp 컨테이너에 배치할 수 있는 웹 애플리케이션 압축 파일 포맷이다.
    • Servlet Context 관련 파일들로 패키징 되어 있다.
    • WAR는 웹 응용 프로그램을 위한 포맷이기 때문에 웹 관련 자원만 포함하고 있으며, 이를 사용하면 웹 애플리케이션을 쉽게 배포 및 테스트가 가능하다.
    • 사전 정의된 구조를 사용하며, WAR 파일 실행을 위해서는 Tomcat, Weblogic, Websphere 등의 웹 서버 또는 WAS가 필요하다.
    • WAR 파일도 Java의 JAR 옵션을 이용해 생성하는 JAR 파일의 일종으로, 웹 애플리케이션 전체를 패키징하기 위한 JAR 파일로 생각하면 된다.

✅pom.xml

  • 메이븐의 기능을 사용하기 위해 작성하는 파일.

메이븐의 생명주기

  • 메이븐의 기능은 생명주기 순서에 따라 관리되고 동작.

Default 생명주기

  • validate : 프로젝트를 빌드하는데 필요한 모든 정보를 사용할 수 있는지 검토.
  • compile : 프로젝트의 소스코드를 컴파일.
  • test : 단위 테스트 프레임워크를 사용해 테스트 실행.
  • package : 컴파일한 코드를 가져와서 JAR 등의 형식으로 패키징 수행.
  • verify : 패키지가 유효하며 일정 기준을 충족하는지 확인.
  • install : 프로젝트를 사용하는데 필요한 패키지를 로컬 저장소에 설치.
  • deploy : 프로젝트를 통합 또는 릴리스 환경에서 다른 곳에 공유하기 위해 원격 저장소에 패키지를 복사.

Clean 생명주기

  • clean : 이전 빌드가 생성한 모든 파일 제거.

Site 생명주기

  • site : 메이븐의 설정 파일 정보를 기반으로 프로젝트의 문서 사이트 생성.
  • site-deploy : 생성된 사이트 문서를 웹 서버에 배포.

🌟API를 작성하는 다양한 방법

  • @RestController()

  • @RequestMapping() : Controller 클래스 수준에서 공통으로 사용될 URL 설정.

  • 스프링 4.3 버전 이후 @RequestMapping(value,method) 대신에 사용하는 어노테이션

    • @GetMapping
    • @PostMapping
    • @PutMapping
    • @DeleteMapping

✅GET API

  • 서버에서 값을 가져올 때 사용하는 API.

@PathVariable 활용하여 URL 자체에 값을 요청하는 방식

  • 만약, @GetMapping 어노테이션에 지정한 변수명과 메서드 매개변수 일므을 동일하게 설정하기 어려운 경우, @PathVariable 뒤에 괄호를 통해 @GetMapping 어노테이션에 사용된 변수명을 지정한다.
@GetMapping(value="/variable/{variable}")
public String getVariable(@PathVariable("variable") String var){
	return var;
}

@RequestParam 어노테이션을 활용하여 쿼리 형식으로 값을 전달

  • 쿼리 스트링에 키 값을 기준으로 메서드의 매개변수명을 매핑하여 가져온다.
  • 일반적으로 값을 기입하지 않은 경우도 있기 때문에, 매개변수의 항목이 일정하지 않게 되므로 Map 객체로 받는것이 효율적이다.
@GetMapping(value="/request")
public String getRequestParam(@RequestParam Map<String,String> param){
	StringBuilder sb = new StringBuilder();
    
    param.setEntry().forEach(map -> {
    	sb.append(map.getKey() + " : " + map.getValue() + "\n");
    });
    
    return sb.toString();
}

URL 과 URI

  • URL : 우리가 흔히 말하는 웹 주소를 의미.리소스가 어디에 있는지 알려주기 위한 경로.
  • URI : 특정 리소스를 식별할 수 있는 식별자를 의미.
  • 웹에서는 URL을 통해 리소스가 어느 서버에 위치해 있는지 알 수 있으며, 그 서버에 접근해서 리소스에 접근하기 위해서는 대부분 URI가 필요하다.

DTO 객체를 활용한 GET 메서드 구현

  • DTO란?
    Data Transfer Object의 약자로, 다른 레이어 간의 데이터 교환에 활용.
@GetMapping(value="/request")
public String getRequestParam(@RequestParam MemberDto dto){
	return dto.toString();
}

✅POST API

  • 웹 애플리케이션을 통해 데이터 베이스 등의 저장소에 리소스를 저장할 때 사용되는 API.
  • 저장하고자 하는 리소스나 값을 HTTP 바디 안에 담아서 서버에 전달.

@RequestBody를 활용하여 POST 메서드 구현

  • POST 요청에서는 리소스를 담기 위해 HTTP Body 안에 값을 넣어 전송.
  • 일반적으로 JSON 형식으로 전송.
  • @RequestBody는 HTTP의 Body 내용을 해당 어노테이션이 지정된 객체에 매핑해준다.

✅PUT API

  • 웹 애플리케이션 서버를 통해 데이터베이스와 같은 저장소에 존재하는 리소스 값을 업데이트 하는데 사용.
  • POST API와 거의 동일하며, HTTP Body를 활용해야 한다.

@ResponseEntity를 활용

  • HttpEntity라는 내장 객체가 있는데, 이는 헤더와 바디로 구성된 HTTP 요청과 응답을 구성하는 역할을 한다.
  • 일반적으로, @ResponseEntity를 사용하여 HttpEntity로 부터 HttpHeaders와 Body를 가지고 자체적으로 HttpStatus를 구현한다.
Ex)
@PutMapping("/member3")
public ResponseEntity<MemberDto> postMemberDto(@RequestBody MemberDto dto){
	return ResponseEntity.status(HttpStatus.ACCEPTED).body(dto);
}

/**
응답 결과
202 응답 코드 발생.
*/

✅DELETE API

  • 웹 애플리케이션 서버를 거쳐 데이터베이스 등의 저장소에 있는 리소스를 삭제할 때 사용.
  • 클라이언트로부터 리소스를 식별할 수 있는 값을 받아 데이터베이스나 캐시에 있는 리소스를 조회하고 삭제하는 역할을 수행.
  • GET 메서드와 같이 URI에 값을 넣어 요청을 받는 형식으로 구현.

🌟REST API 명세를 문서화 하는 방법 - Swagger

  • API를 개발하면 명세 관리가 필요하다.

  • 명세 : 해당 API가 어떤 로직을 수행하는지 설명하고 이 로직을 수행하기 위해 어떤 값을 요청하며, 이에따른 응답값으로는 무엇을 받을 수 있는지를 정리한 자료를 의미한다.

  • 즉, 협엽시에 협업자에게 API에 대한 로직을 추가해줌으로서 원활한 의사소통을 위해 필요하다.

  • API 개발 과정에서 명세 문서의 주기적인 업데이트가 필요하며, 이를 위해 사용하는 것이 'Swagger'이다.

✅Swagger 설정

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.PathSelectors;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

@Configuration
@EnableSwagger2
public class SwaggerConfig {
    @Bean
    public Docket api(){
        return new Docket(DocumentationType.SWAGGER_2)
                .apiInfo(apiInfo())
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.springboot.api"))
                .paths(PathSelectors.any())
                .build();
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder()
                .title("Spring Boot Open API Test with Swagger")
                .description("설명 부분")
                .version("1.0.0")
                .build();
    }
}

✅Swagger 명세 추가

 @ApiOperation(value="GET 메서드 예제", notes="@RequestParam을 활용한 GET Method")
    @GetMapping("/request4")
    public String getRequestParam4(
            @ApiParam(value="이름",required = true) @RequestParam String name,
            @ApiParam(value="이메일",required=true) @RequestParam String email,
            @ApiParam(value="회사",required=true) @RequestParam String organization
    ){
        return name + ", " + email + ", " + organization;
    }
  • @ApiOperation : 대상 API의 설명을 작성하기 위한 어노테이션.
  • @ApiParam : 매개변수에 대한 설명 및 설정을 위한 어노테이션, 메서드 매개변수 뿐만 아니라 DTO 객체를 매개변수로 사용 시 DTO 클래스 내의 매개변수 정의도 가능하다.

trouble shooting

  • 원인 : 구글링 결과, spring boot 2.7.14 버전과 Swagger 사이의 버전 오류로 인한 것이었다.
  • 해결 방안
    1. Spring boot 버전을 2.4.2로 낮춘다.
    2. Swagger 설정한 Config 클래스에서 WebMvcConfigurationSupport를 구현 및 확장하는 방법이다.
    → Spring Boot가 제공하는 WebMVC 자동 설정을 사용하지 않기 때문에 일부 api 사용이 불가함.
    3. springdoc-openapi-ui 적용(적용 방법 설명 링크 참고)
  • 1번 해결방안으로 해결함.
profile
백엔드 서버 엔지니어

0개의 댓글