백엔드/Spring Boot

2. 스프링 부트 시작하기 (2) - 스프링 부트 둘러보고 코드 이해하기

두개의 문 2023. 7. 11. 17:17

3. 스프링 부트3 둘러보기 

1) 첫 번째 스프링 부트3 예제 만들기 

 

① TestController.java 

   - 사용자가 /test GET 요청 시, "Hello, World!" 문자열을 반환 

package org.choongang.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController 
// 라우터 역할 : HTTP 요청과 메서드를 연결하는 장치 
public class TestController { 
	@GetMapping("/test")
	public String hello() {
		return "Hello, World!";
	}
}

 

▪︎ @RestController

  - 라우터 역할을 하는 애너테이션

  - 라우터 : HTTP 요청과 메서드를 연결하는 장치 

    → 이 애너테이션이 있어야 클라이언트 요청에 맞는 메서드 실행 가능 

  - @Controller 애너테이션에 @ResponseBody 애너테이션이 합쳐진 결과물

 

 

② 제대로 동작하는지 확인 

    - 스프링 부트 실행 : 프로젝트에서 Run As - Spring Boot App 클릭 

    - 웹 브라우저에 'http://localhost/test'로 접속하면 다음과 같이 출력됨 

▪︎ '@GetMapping' 애너테이션으로 메서드와 매핑할 때, 스프링 부트에서 설정한 경로

   → 위와 같이 웹 브라우저에서 해당 경로를 입력하면, 문자열이 출력됨 

 

   ( 참고 )

    서버 포트 변경은 application.properties에서 가능 ( 8080 → 80으로 변경 ) 

 

 

 


2) 스프링 부트 스타터 살펴보기 

 

◉ 스프링 부트 스타터 

  ▪︎ 의존성이 모여 있는 그룹으로, 스타터를 사용하면 필요한 기능을 간편하게 설정 가능 

  ▪︎ 스타터 명명규칙 : spring-boot-starter-{작업유형}

    

 

◉ 자주 사용하는 스타터 정리 

스타터 설명
spring-boot-starter-web Spring MVC를 사용해서 RESTful 웹 서비스를 개발할 때 필요한 의존성 모음 
spring-boot-starter-test 스프링 애플리케이션을 테스트하기 위해 필요한 의존성 모음 
spring-boot-starter-validation 유효성 검사를 위해 필요한 의존성 모음 
spring-boot-starter-actuator 모니터링을 위해 애플리케이션에서 제공하는 다양한 정보를 제공하기 쉽게 하는 의존성 모음
spring-boot-starter-data-jpa ORM을 사용하기 위한 인터페이스의 모음인 JPA를 더 쉽게 사용하기 위한 의존성 모음 

 

 

현재 프로젝트의 build.gradle 확인해보자. 

dependencies {
	// * Spring MVC 개발 라이브러리 
	// MVC 환경 개발에 필요한 필수 라이브러리 
	implementation 'org.springframework.boot:spring-boot-starter-web'

	// * 테스트 라이브러리 
	testImplementation 'org.springframework.boot:spring-boot-starter-test'
}

 


3) 스프링 부트3과 자바 버전 

 

▪︎ 스프링 부트 3 이전과 이후는 사용할 수 있는 자바의 범위가 다름 

  • 스프링 부트 2 : 자바 8 버전 이상 사용 

  • 스프링 부트 3 : 자바 17 버전 이상 사용해야 함 

 

▪︎ 자바 17의 주요 변화인 텍스트 블록, 레코드, 패턴 매칭에 대해 알아보자 

 

 

◉ 텍스트 블록 

  ▪︎ 이전 버전 : 여러 줄의 텍스트를 작성하기 위해서 '\n' 추가 

  ▪︎ 이제는 """로 감싼 텍스트를 사용해 여러 줄의 텍스트 표현 가능 

    ⇒ 가독성 향상됨

// * 이전 버전 
String query11 = "SELECT * FROM \"items\"\n" +
 				 "WHERE \"status\" = \"ON_SALE\"\n" +
                 "ORDER BY \"price\";\n";
                 
// * 17 버전 
String query17 = """
		 SELECT * FROM "items"
                 WHERE "status" = "ON_SALE"
                 ORDER BY "price";
                 """;

 

 

◉ formatted() 메서드 

  ▪︎ 값을 파싱하기 위한 메서드 제공 

// * 파싱을 위한 formatted() 메서드
String textBlock17 = """
{
	"id" : %d
    "name" : %s,
}
""".formatted(2, "juice");

 

 

◉ 레코드 

  ▪︎ 데이터 전달을 목적으로 하는 객체를 더 빠르고 간편하게 만들기 위한 기능 

  ▪︎ 상속을 할 수 없고, 파라미터에 정의한 필드는 private final로 정의됨 

  ▪︎ getter를 자동으로 만들기 때문에 애너테이션이나 메서드로 게터 정의를 하지 않아도 됨 

// * 레코드의 사용 예
record Item(String name, int price){
	// 이렇게 하면 파라미터가 private final로 정의됨 
}

Item juice = new Item("juice", 3000);
juice.price();    // 3000

 

 

◉ 패턴 매칭 

  ▪︎ 타입 확인을 위해 사용하던 instanceof 키워드를 조금 더 쉽게 사용할 수 있게 해줌 

  ▪︎ 이전에는 instanceof 키워드와 형변환 코드 조합해야 했지만, 이제는 바로 형변환 가능 

// * instanceof 키워드의 사용 예
//  11 버전 
if ( o instanceof Integer){
	Integer i = (Integer) o;	// 형변환 코드 
    ... 생략 ...
}

//  17 버전 
if ( o instanceof Integer i){
	... 생략 ...
}

 

 

◉ 자료형에 맞는 case 처리 

  ▪︎ switch-case문으로 자료형에 맞게 case 처리 가능 

// * 자료형 case 처리 예
static double getIntegerValue(Object o){
	return switch(o) {
    	case Double d -> d.intValue();
        case Float f -> f.intvalue();
        case String s -> Integer.parseInt(s);
        default -> 0d;
    };
}

 

 

◉ Servlet, JPA의 네임 스페이스가 Jakarta로 대체 

  ▪︎ 패키지 네임 스페이스가 javax.*에서 jakarta.*로 변경되었음 

 

 

◉ GraalVM 기반의 스프링 네이티브 공식 지원

  ▪︎ 스프링 애플리케이션을 네이티브 이미지로 컴파일해 JVM에 구동되는 애플리케이션에 비해 시작시간과 메모리 오버 헤드를 줄일 GraalVM 기반의 스프링 네이티브를 공식 지원함 

  ▪︎ JVM 실행 파일과 비교해 네이티브 이미지를 사용하면 가동 시간이 짧아지고, 메모리를 적게 소모함 

 

 


4. 스프링 부트 3 코드 이해하기 

1) @SpringBootApplication 이해하기 

 

① SpringBootDeveloperApplication.java

package me.leedahee;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SpringbootDeveloperApplication {

	public static void main(String[] args) {
		SpringApplication.run(SpringbootDeveloperApplication.class, args);
	}
}

 ▪︎ 이 클래스는 자바의 main() 메서드와 같은 역할로, 여기서 스프링 부트가 시작됨 

 ▪︎ @SpringBootApplication 애너테이션  

   : 스프링 부트 사용에 필요한 기본 설정해주는 역할 

 ▪︎ SpringApplication.run() 메서드 

   : 애플리케이션을 실행하는 역할로, 

    ❶ 첫 번째 인수 : 스프링 부트 3 애플리케이션의 메인 클래스로 사용할 클래스  

    ❷ 두 번째 인수 : 커맨드 라인의 인수들을 전달 

 

 

 ▪︎ 이클립스에서 @SpringBootApplication 애너테이션을 cmd 키와 함께 마우스 클릭 

   → @SpringBootApplication 애너테이션의 구성 나옴 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Inherited
@SpringBootConfiguration  // * 스프링 부트 관련 설정 
@EnableAutoConfiguration  // * 자동으로 등록된 빈을 읽고 등록 
@ComponentScan(excludeFilters = { 
	@Filter(type = FilterType.CUSTOM, 
    	// * 사용자가 등록한 빈을 읽고 등록 
    		classes = TypeExcludeFilter.class),
	@Filter(type = FilterType.CUSTOM, 
    		classes = AutoConfigurationExcludeFilter.class) })
public @interface SpringBootApplication {
		...생략...
}

  ❶ @SpringBootConfiguration

    - 스프링 부트 관련 설정을 나타내는 애너테이션으로, @Configuration을 상속해서 만든 애너테이션 

 

 

  ❷ @ComponentScan

    - 사용자가 등록한 빈을 읽고 등록하는 애너테이션 

    - @Component라는 애너테이션을 가진 클래스를 찾아 빈으로 등록하는 역할 

    - 항상 @Component 애너테이션을 사용하지 않고, 용도에 따라 다른 애너테이션을 사용함 

애너테이션명 설명
@Configuration 설정파일 등록
@Repository ORM 매핑
@Controller, @RestController 라우터
@Service 비즈니스 로직 

   ⇒ 위의 애너테이션 모두 @Component 애너테이션을 포함하고 있음 

       ( 스프링 컨테이너에 의해 빈으로 생성되어 관리된다 ) 

 

 

  ❸ @ EnableAutoConfiguration

    - 스프링 부트에서 자동 구성을 활성화하는 애너테이션 

    - 스프링 부트 서버가 시작할 때 스프링 부트의 메타 파일을 읽고 정의된 설정들을 자동으로 구성하는 역할을 수행  

 


2) 테스트 컨트롤러 살펴보기 

 

◉ 스프링 컨테이너가 빈을 관리한다. 실제로 작성한 TestController.java 파일을 통해 빈이 어떻게 등록되는지 살펴보자 

@RestController 
// 라우터 역할 : HTTP 요청과 메서드를 연결하는 장치 
public class TestController { 
    // /test GET 요청이 오면 test() 메서드 실행 
    @GetMapping("/test")	
	public String hello() {
		return "Hello, World!";
	}
}

 ▪︎ @RestController 

  - 라우터 역할을 하는 애너테이션 

  - 라우터란? HTTP 요청과 메서드를 연결하는 장치를 말함 

  → 이 애너테이션이 있어야 클라이언트의 요청에 맞는 메서드를 실행할 수 있음 

  -  RestController의 경우, 주로 2가지 방법으로 생성함 

    1. 클래스 전체를 RestController로 만드는 방법

      → 클래스 정의부에 '@RestController'주석 추가 

    2. 컨트롤러 클래스의 일부 라우팅 메소드를 Rest 응답 메서드로 만드는 방법 

      → 반환 데이터형 앞 또는 메서드 이름 위에 '@ResponseBody'주석 추가 

 

 

◉ @RestController와 @Component는 애너테이션 용어가 다른데 어떻게 같은 @Component처럼 취급하는 것일까?

 

① @RestController를 구현하는 RestController.java 파일로 이동 

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Controller
@ResponseBody
public @interface RestController {

	/**
	 * The value may indicate a suggestion for a logical component name,
	 * to be turned into a Spring bean in case of an autodetected component.
	 * @return the suggested component name, if any (or empty String otherwise)
	 * @since 4.0.1
	 */
	@AliasFor(annotation = Controller.class)
	String value() default "";

}

 ▪︎ 코드를 보면, @Controller, @RequestBody 애너테이션이 함께 존재           

 ▪︎ @Controller + @RequestBody ⇒ @RestController 애너테이션 

 

 

② @Controller 애너테이션의 구현 파일인 Controller.java 파일로 이동

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Component
public @interface Controller {
	...생략...
}

 ▪︎ @Component 애너테이션 발견! 

   → @Controller 애너테이션이 @ComponentScan을 통해 빈으로 등록되는 이유 

       : 바로 @Controller 애너테이션에서 @Component 애너테이션을 가지고 있기 때문 

 

 


 - 스프링 : 엔터프라이즈 애플리케이션을 쉽게 개발할 수 있도록 도와주는 프레임워크 

 - 스프링 부트 : 스프링을 더 빠르고 쉽게 사용하기 위한 도구로서, 스타터와 자동 구성을 제공함 

 - IoC : 제어의 역전 / DI : 의존성 주입 

 - 애너테이션 : 자바 소스 코드에 추가하는 표식 ( JDK 1.5 버전부터 사용 가능 )

  

 - @SpringBootApplication의 경우, 다음의 애너테이션들로 구성되어 있음

  • @SpringBootConfiguration : 스프링 부트 관련된 설정

  • @ComponentScan : 사용자가 등록한 빈을 읽고 등록

  • @EnableAutoConfiguration : 자동 설정으로 등록되는 빈을 읽고 등록 

 

- @Component 애너테이션이 있는 클래스는 빈으로 등록됨 

- @Controller, @RestController, @Configuration, @Repository, @Service 모두 @Component 애너테이션을 가지고 있음 

  → 때에 따라 알맞은 애너테이션 선택하여 사용 

 


 


JSP 파일 생성 시, 첫 줄에서 에러난 경우 해결 방법 

( 이전 시간에 정리해둔 블로그 글 참고 )

https://daheelee.tistory.com/41