02. 스프링 부트 3 시작하기

Ogu·2024년 1월 2일
0

스프링과 스프링부트

스프링의 등장

엔터프라이즈 애플리케이션이란 대규모의 복잡한 데이터를 관리하는 애플리케이션을 말합니다. 몇백만, 몇천만의 사용자 요청을 동시에 처리하기 위해서는 서버 성능과 안정성, 보안이 매우 중요합니다.

이러한 상황에서 서버 성능, 안정성, 보안을 매우 높은 수준으로 제공하는 스프링 프레임워크가 등장했습니다.

스프링부트

하지만 스프링은 설정이 매우 복잡했습니다. 따라서 스프링 개발팀에서 이러한 단점을 인식하고 스프링 프레임워크를 더 빠르게 이용할 수 있도록 스프링 부트를 출시했습니다.

스프링부트로 빠르게 스프링 프로젝트를 설정할 수 있고, 스타터를 사용해 간편하게 의존성을 사용하거나 관리할 수 있습니다. 개발자가 비즈니스 로직 개발에만 집중할 수 있도록 하는 것이죠.

스프링부트의 특징

  • 톰캣 웹 서버 내장
  • 스프링 부트 스타터 제공 - 빌드 구성 단순화
  • XML 설정 없이 자바 코드로 모두 작성
  • JAR를 이용한 자바 옵션만으로 배포
  • 모니터링 및 관리 도구 스프링 액츄에이터 제공
  • 인메모리 DB 지원

구성의 차이

스프링은 필요 환경들을 수동으로 구성하지만, 스프링 부트는 스프링 코어와 스프링 MVC의 모든 기능을 자동으로 로드합니다.

내장 WAS의 유무

스프링 애플리케이션은 일반적으로 톰캣과 같은 WAS에서 배포되는데, 스프링 부트는 WAS를 자체적으로 내장하고 있습니다. 따라서 jar파일만 빌드하면 별도의 WAS 설정 없이 어플리케이션 실행이 가능합니다.

스프링의 주요 개념

스프링의 주요 개념인 IoC, DI, AOP, PSA에 대해 알아보도록 하겠습니다.

제어 역전 (IoC)

IoC는 Inversion of Control의 줄임말입니다.

지금까지는 클래스 작성 후 객체를 직접 생성했지만, 제어의 역전은 외부에서 관리하는 객체를 가져와 직접 사용하는 것을 말합니다.

스프링에서는 스프링 컨테이너가 객체를 관리하고 제공합니다.

  • 클래스 A에서 클리스 B 객체 생성
    public class A {
    	b = new B();
    }
  • 스프링 컨테이너가 객체 관리
    public class A {
    	private B b;
    }
    → 코드에서 객체 생성 X, 어디선가 받아온 객체를 b에 할당

의존성 주입(DI)

DI는 제어의 역전을 구현하기 위해 사용하는 방법으로, Dependency Injection의 줄임말입니다. 어떤 클래스가 다른 클래스에 의존한다는 뜻을 갖고 있습니다.

예를 들어 @Autowired 는 스프링 컨테이너에 있는 빈이라는 것을 주입합니다. 빈은 스프링 컨테이너에서 관리하는 객체입니다.

  • 객체 주입 예시
    public class A {
    	// A에서 B를 주입받음
    	@Autowired
    	private B b;
    }

위와 같이 작성할 수 있는 이유는 스프링 컨테이너에서 객체를 주입했기 때문입니다. 즉, 스프링 컨테이너가 B 객체를 만들어 클래스 A에 줍니다.

💡 빈과 스프링 컨테이너

스프링 컨테이너

스프링 컨테이너는 빈이 생성되고 소멸되기까지의 생명 주기를 관리합니다.

빈이란?

스프링 컨테이너가 생성하고 관리하는 객체로, 스프링은 빈을 스프링 컨테이너에 등록하기 위해 XML 설정, 애너테이션 추가 등의 여러 방법을 제공합니다.
예를 들어 MyBean이라는 클래스에 @Component 애너테이션을 붙이면 해당 클래스가 빈으로 등록되어 스프링 컨테이너에서 관리합니다. 빈의 이름은 클래스 이름의 첫글자를 소문자로 바꾸어 등록됩니다.

@Component
public class MyBean {
}

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

AOP는 Aspect Oriented Programming의 줄임말로, 즉 관점 지향 프로그래밍을 뜻합니다. 프로그래밍에 대한 관점을 핵심 관점, 부가 관점으로 나누어 관심 기준으로 모듈화 하는 것을 의미합니다.

예를 들어, 계좌 관리 프로그램이 있다면 핵심 관점을 계좌 이체, 고객 관리, 이자 계산 등으로, 부가 관점을 로깅, 데이터베이스 연결, 트랜젝션 등의 로직으로 둘 수 있습니다.

위와 같이 부가 관점에 해당하는 로직을 모듈화하여 핵심 관점 코드에서 분리할 수 있도록 합니다. 따라서 핵심 관점 코드에만 집중할 수 있고, 프로그램 변경과 확장에 유연해집니다.

이식 가능한 서비스 추상화 (PSA)

PSA는 Portable Service Abstraction의 줄임말로, 이식 가능한 서비스 추상화를 뜻합니다. 스프링에서 제공하는 다양한 기능들을 추상화하여 개발자가 더 쉽게 사용하는 인터페이스들을 말합니다.

PSA의 대표적인 예로 클라이언트의 매핑과 클래스, 매서드의 매핑을 위한 애너테이션이 있습니다.

예를 들어, 데이트베이스 접근 기술에는 JPA, MyBatis, JDBC가 있는데, 어떤 기술을 사용하든 일관된 방식으로 데이터베이스에 접근할 수 있도록 인터페이스를 지원합니다.

또 다른 예시로, WAS를 톰캣 대신 언더토우, 네티와 같은 다른 곳에서 실행해도 기존 코드로 그대로 실행할 수 있습니다.

스프링 부트 3 둘러보기

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

@RestController
public class TestController {
    @GetMapping("/test")
    public String test() {
        return "Hello, world!";
    }
}
  • https://localhost:8080/test 접속
  • localhost : 127.0.0.1로, 현재 사용중인 컴퓨터
  • 8080 : 스프링 부트의 포트 번호
  • test : @GetMapping 애너테이션으로 매서드와 매핑할 때 스프링 부트에서 설정한 경로

스프링 부트 스타터

스프링 부트 스타터는 의존성이 모여있는 그룹으로, 필요한 기능들을 간편하게 설정할 수 있도록 도와줍니다. 스프링부트는 현재 버전에 맞는 라이브러리를 알아서 관리합니다.

스타터는 spring-boot-starter-{작업유형} 이라는 명명규칙을 따릅니다.

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

자동 구성

스프링 부트는 애플리케이션이 최소한의 설정만으로도 실행되도록 여러 부분을 자동으로 구성합니다. 서버를 시작할 때 구성 파일을 읽어와 자동 설정을 합니다.

자동 설정은 META-INF 에 있는 spring.factories 파일에 담겨 있습니다.

  • 오른쪽 상단 돋보기 → Files → spring=boot-autoconfigure/spring.factories 입력 → 첫 번째 파일 클릭
  • 해당 파일의 텍스트들이 프로젝트에 쓰일 구성 후보들로, 스프링 부트 시작 시 해당 파일에 설정되어 있는 클래스들을 모두 불러오고, 이후에 프로젝트에서 사용할 것들만 자동으로 구성해 등록합니다.

스프링 부트 3과 자바 버전

  • 스프링 부트 2.xx → 자바 8 버전 이상
  • 스프링 부트 3.xx → 자바 12 버전 이상

자바 17 버전 이후 기능

  • 텍스트 블록
    • 기존에는 여러 줄의 텍스트 작성을 위해 \n 을 추가했지만 자바 17 이후 """ 로 감싸 여러 줄의 텍스트 작성

      # 기존의 문자열 조합 방식
      String query11 = "SELECT * FROM \"items\"n" +
      									"WHERE \"status\" = "ON_SALE\"\n" +
      									"ORDER BY \"price\"'\n";
      
      String query17 = """
      									SELECT * FROM "items"
      									WHERE "status" = "ON_SALE"
      									ORDER BY "price"
      									""";
  • formatted() 메서드
    • 값을 파싱하기 위한 formatted() 메서드도 제공

      String tecxtBlock17 = """
      {
      	"id": %d
      	"name": %s,
      }
      """.formatted(2, "juice");
  • 레코드
    • 데이터 전달을 목적으로 하는 객체를 더 빠르고 간편하게 만들기 위한 기능

    • 상속 불가능, 파라미터에 정의한 필드는 private final로 정의

    • getter 자동 생성, 따라서 애너테이션이나 메서드로 getter 정의 X

      record Item(String name, int price) {
      	// 파라미터가 private final로 정의됨
      }
      Item juice = new Item("juice", 3000);
      juice.price(); // 3000
  • 패턴 매칭
    • 패턴 매칭 타입 확인을 위한 instanceof 키워드를 조금 더 쉽게 사용

      // 11 버전
      if (o instanceof Integer) {
      	Integer i = (Integer) o;
      ...
      }
      
      // 17 v
      if (o instanceof Integer i) {
      }
  • 자료형에 맞는 case 처리
    static double getIntegerValue(Object o) {
    	return switch(o) { d
    		case Double d -> d.intValue();
    		case Float f -> f.intValue();
    		case String s -> Integer.parseInt(s);
    		default -> 0d;
    	};
    }
  • Servlet, JPA의 네임 스페이스가 Jarkarta로 대체
    • 패키지 네임스페이스 javax.*jakarta.* 변경
  • GraalVM 기반의 스프링 네이티브 공식 지원

스프링부트3 코드

@SpringBootApplication

  • 자바의 main() 메서드 기능, 스프링 부트 시작
  • 스프링 부트 사용에 필요한 기본 설정
@SpringBootApplication
public class UmustbeApplication {

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

}
  • [SpringApplication.run](http://SpringApplication.run)()

    • 첫 번째 인수 → 어플리케이션 메인 클래스
    • 두 번째 인수 → 커맨드 라인의 인수들 전달
  • @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 : 스프링 부트 관련 설정
    • @ComponentScan : 사용자가 등록한 빈을 읽고 등록하는 애너테이션
      • Component 애너테이션을 가진 클래스들을 찾아 빈으로 등록
      • @Component 를 감싸는 애너테이션 예시
        • @Configuration , @Repository , @Controller , @RestController , @Service
    • @EnableAutoConfiguration : 자동 구성 활성화
      • 스프링 부트 실행 시 메타 파일을 읽고 정의된 설정들을 자동으로 구성
        (spring.factories)

Controller

@RestController
public class TestController {
	@GetMapping("/test")
	public String test() {
		return "Hello, world!";
	}
}

→ /test GET 요청이 들어오면 test() 메서드 실행

  • @RestController : 라우터 역할 (HTTP 요청과 메서드를 연결하는 장치)
  • @RestController@Controller, @ResponseBody 애너테이션이 포함됨
  • @Controller 애너테이션은 @Component 포함
profile
私はゲームと日本が好きなBackend Developer志望生のOguです🐤🐤

0개의 댓글