본문 바로가기
Backend/<스프링 부트 3 백엔드 개발자 되기>

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

by ccooll 2023. 10. 27.

2.1 스프링과 스프링 부트

1. 스프링의 등장

- 엔터프라이즈 애플리케이션

: 대규모의 복잡한 데이터를 관리하는 애플리케이션

  서버 성능, 안정성, 보안 매우 중요

  엔터프라이즈 애플리케이션을 위한 개발 환경 제공 → 스프링 프레임워크

 

 

2. 스프링을 더 쉽게 만들어주는 스프링 부트

 스프링, 설정 매우 복잡하다는 단점 → 스프링 부트 출시

 

- 스프링 부트

: 스프링 프레임워크를 더 쉽고 빠르게 이용할 수 있도록 만들어주는 도구

  빠르게 스프링 프로젝트 설정 가능, 의존성 세트라고 불리는 스타터를 사용해 간편하게 의존성 사용, 관리 가능

 

- 스프링 부트의 주요 특징

: 톰캣, 제티, 언더토우 같은 웹 애플리케이션 서버가 내장되어 있어서 따로 설치를 하지 않아도 독립적으로 실행할 수 있음

  빌드 구성을 단순화하는 스프링 부트 스타터를 제공함

  XML 설정을 하지 않고 자바 코드로 모두 작성할 수 있음

  JAR을 이용해서 자바 옵션만으로도 배포가 가능

  애플리케이션의 모니터링 및 관리 도구인 스프링 액츄에이터를 제공함

 

- 스프링과 스프링 부트의 차이점

1. 구성의 차이

 - 스프링 : 애플리케이션 개발에 필요한 환경을 수동으로 구성하고 정의해야 함

 - 스프링 부트 : 스프링 코어와 스프링 MVC의 모든 기능을 자동으로 로드, 수동으로 개발 환경을 구성할 필요 없음

 

2. 내장WAS의 유무

 - 스프링 : 일반적으로 톰캣과 같은 WAS에서 배포됨 (WAS : 간단히 웹 애플리케이션을 실행하기 위한 장치)

 - 스프링 부트 : WAS를 자체적으로 가지고 있음, jar 파일만 만들면 별도의 WAS 설정을 하지 않아도 애플리케이션 실행 가능, 내장 WAS에는 톰캣, 제티, 언더토우가 있어서 상황에 필요한 WAS를 선택할 수 있음

 

 

 

2.2 스프링 콘셉트 공부하기

1. 제어의 역전과 의존성 주입

: 스프링은 모든 기능의 기반을 제어의 역전(IoC)와 의존성 주입(DI)에 두고 있음.

 

- IoC (Inversion of Control)

; 다른 객체를 직접 생성하거나 제어하는 것이 아니라 외부에서 관리하는 객체를 가져와 사용하는 것

 

// 클래스 B 객체를 사용하기 위해 클래스 A에서 new 키워드로 클래스 B의 객체 생성 

public class A{
	b = new B();
}

 // 코드에서 객체를 생성하지 않고 어디선가 받아온 객체를 b에 할당함

public class A {
	private B b;
}

- DI (Dependency Injection)

: IoC를 구현하기 위해 사용하는 방법

  어떤 클래스가 다른 클래스에 의존한다는 뜻

 

// A에서 B를 주입받음

: 이전 코드에서는 개발자가 직접 B 객체를 생성했지만 다음 코드는 B b;라고 선언했을 뿐 직접 객체를 생성하지는 않고 있음. 즉 객체를 주입받고 있음

→ 스프링 컨테이너라는 곳에서 객체를 주입함. 즉 스프링 컨테이너가 B 객체를 만들어서 클래스 A에 줌.

public class A {
    @Autowired
    B b;	// B = 빈
}

@Autowired : 스프링 컨테이너에 있는 빈이라는 것을 주입하는 역할

빈 : 스프링 컨테이너에서 관리하는 객체

 

 

2. 빈과 스프링 컨테이너

- 스프링 컨테이너

: 스프링은 스프링 컨테이너를 제공하고 스프링 컨테이너는 빈을 생성하고 관리함

  즉, 빈이 생성되고 소멸되기까지의 생명주기를 이 스프링 컨테이너가 관리하는 것

 

- 빈

: 스프링 컨테이너가 생성하고 관리하는 객체

  바로 앞에서 본 코드에서 B가 바로 빈임.

  스프링은 빈을 스프링 컨테이너에 등록하기 위해 XML 파일 설정, 애너테이션 추가 등 여러 방법을 제공함

  

ex) @Component 애너테이션 → 클래스 MyBean을 빈으로 등록

@Component
public class MyBean{
}

 이후 스프링 컨테이너에서 이 클래스를 관리함

 이때 빈의 이름은 클래스 이름의 첫 글자를 소문자로 바꿔 관리 → 위 코드의 경우 myBean

※ 빈 = 스프링의 객체

 

 

3. 관점 지향 프로그래밍

- AOP (Aspect Oriented Programming)

: 관점 지향 프로그래밍, 프로그래밍에 대한 관심을 핵심 관점, 부가 관점으로 나누어서 관심 기준으로 모듈화 함

 

 

4. 이식 가능한 서비스 추상화

- PSA (Portable Service Abstraction)

: 스프링에서 제공하는 다양한 기술들을 추상화해 개발자가 쉽게 사용하는 인터페이스

 

 

** 한 줄로 정리하는 스프링 핵심 4가지 **

더보기

1. IoC : 객체의 생성과 관리를 개발자가 하는 것이 아니라 프레임워크가 대신하는 것

2. DI : 외부에서 객체를 주입받아 사용하는 것

3. AOP : 프로그래밍을 할 때 핵심 관점과 부가 관점을 나누어서 개발하는 것

4. PSA : 어느 기술을 사용하던 일관된 방식으로 처리하도록 하는 것

 

 

2.3 스프링 부트 3 둘러보기

1. 스프링 부트 3 예제 만들기

① TestController.java

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

: 사용자가 /test GET 요청을 하면 "Hello, world!" 문자열을 반환하게 해줌

 

② http://localhost:8080/test 접속

 localhost : 루프백 호스트명, 현재 사용 중인 컴퓨터를 의미

 8080 : 스프링 부트의 포트 번호

 /test : @GetMapping이라는 애너테이션으로 메서드와 매핑할 때 스프링 부트에서 설정한 경로

 

 

2. 스프링 부트 스타터

: 의존성이 모여 있는 그룹

  spring-boot-starter-{작업유형}

 

ex) JDBC 관련 스타터 : spring-boot-starter-jdbc

 

** 자주 사용하는 스타터 **

더보기

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 {
    implementation 'org.springframework.boot : spring-boot-starter-web'
    testImplementation 'org.springframework.boot : spring-boot-starter-test'
}

web 스타터와 test 스타터가 의존성으로 명시되어 있음

 

 

3. 자동 구성

: META-INF에 있는 spring.factories 파일에 담겨 있음

 

 

4. 스프링 부트 3와 자바 버전

자바 17의 주요 변화 

 - formatted() 메서드 : 값 파싱

 - 레코드 : 데이터 전달을 목적으로 하는 객체를 더 빠르고 간편하게 만들기 위한 기능, 레코드는 상속을 할 수 없고 파라미터에 정의한 필드는 private final로 정의됨. 레코드는 getter를 자동으로 만들기 때문에 애너테이션이나 메서드로 게터 정의를 하지 않아도 됨

 

ex)

record Item(String name, int price) {
	// 이렇게 하면 파라미터가 private final로 정의된다
}
Item juice = new Item("juice", 3000);
juice.price();	// 3000

 

 - 패턴 매칭 : 타입 확인을 위해 사용하던 instaceof 키워드를 조금 더 쉽게 사용할 수 있게 해줌. 이전에는 instanceof 키워드와 형변환 코드를 조합해야 했지만 이제는 바로 형변환을 한 다음 사용 가능

 

 - 자료형에 맞는 case 처리

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

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

 

 

 

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

1. @SpringBootApplication 이해하기

 

① SpringBootDeveloperApplication.java

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

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

- @SpringBootApplication 애너테이션을 추가하면 스프링 부트 사용에 필요한 기본 설정을 해줌

- SpringApplication.run() 메서드는 애플리케이션을 실행함

- 첫 번째 인수(SpringBootDeveloperApplication.class) : 스프링 부트 3 애플리케이션의 메인 클래스로 사용할 클래스

- 두 번째 인수(args) : 커맨드 라인의 인수들을 전달함

 

② @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) 
})

@EnableAutoConfiguration
public @interface SpringBootApplication {
	// 생략
}

- @SpringBootConfiguration

: 스프링 부트 관련 설정을 나타내는 애너테이션

  @Configuration을 상속해서 만든 애너테이션

  

- @ComponentScan

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

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

더보기

** @Component 애너테이션 보다는 용도에 따라 다른 애너테이션 사용 **

@Configuration : 설정 파일 등록

@Repository : ORM 매핑

@Controller, @RestController : 라우터

@Service : 비즈니스 로직

 

- @EnableAutoConfiguration

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

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

 

2. 테스트 컨트롤러

 

TestController.java

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

- /test GET 요청이 오면 test() 메서드 실행

- @RestController는 라우터 역할 (라우터 : HTTP 요청과 메서드를 연결하는 장치)

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

- 지금의 경우 TestController 라우터로 지정해 /test GET 요청이 왔을 때 test() 메서드를 실행하도록 구성

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

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

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

 

 

 

** 핵심 요약 **

더보기

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

2. IoC는 제어의 역전, DI는 의존성 주입

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

4. 애너테이션은 자바 소스 코드에 추가하는 표식, 보통 @ 기호를 앞에 붙여서 사용, 주로 메타 데이터(데이터에 대한 설명을 담고 있는 데이터)의 비중이 가장 큼

5. @SpringBootApplication은 스프링 부트 관련된 설정을 하는 @SpringBootConfiguration, 사용자가 등록한 빈을 읽고 등록하는 @ComponentScan, 자동 설정으로 등록되는 빈을 읽고 등록하는 @EnableAutoConfiguration으로 이루어져 있음

6. @Component 애너테이션이 있는 클래스는 빈으로 등록되며, @Controller, @RestController, @Configuration, @Repository, @Service 모두 @Component 애너테이션을 가지고 있음. 때에 따라 알맞은 애너테이션을 선택해야 함