스프링 프레임워크의 등장
: 많은 사용자의 요청을 동시에 처리해야 해서 서버 성능과 안정성, 보안이 중요. 이러한 개발환경 제공을 하는 스프링 프레임워크
스프링 부트는 스프링에 속한 도구로 개발할 때 몇 가지 차이점이 있다
- 구성의 차이
- : 스프링은 애플리케이션 개발에 필요한 환경을 수동으로 구성하고 정의
- 내장 WAS의 유무: 스프링 부트는 WAS를 자체적으로 가지고 있어 별도 WAS설정 없이 실행가능
- : 스플링 애플리케이션은 일반적으로 톰캣과 같은 WAS에서 배포(웹 애플리케이션을 실행하기 위한 장치)
스프링 | 스프링 부트 | |
목적 | 엔터프라이즈 애플리케이션 개발을 더 쉽게 만들기 | 스프링의 개발을 더 빠르고 쉽게 하기 |
설정파일 | 개발자가 수동으로 구성 | 자동 구성 |
XML | 일부 파일은 XML로 직접 생성하고 관리 | 사용하지 않음 |
인메모리 데이터베이스 지원 | 지원하지 않음 | 인메모리 데이터베이스 자동 설정 지원 |
서버 | 프로젝트 띄우는 서버(ex : 톰캣, 제티)를 별도로 수동설정 | 내장형 서버를 제공해 별도의 설정이 필요 없음 |
스프링은 모든 기능의 기반을 제어의 역전(IoC)과 의존성 주입(DI)에 두고 있다
IoC(Inversion of Control, 제어의 역전)
: 여태까지는 객체가 필요한 곳에서 직접 객체를 생성했지만 IoC는 제어의 역전으로서 직접 생성이나 제어가 아닌 외부에서 관리하는 객체를 가져와 사용
기존코드
public class A {
b = new B();
// 클래스 A에서 new 키워드로 클래스 B의 객체 생성
}
IoC방법
public class A {
private B b; // 코드에서 객체 생성이 아닌, 어디선가 받아온 객체 b에 할당
}
DI(Dependency Injection, 의존성 주입)
: IoC 제어의 역전을 통해 객체를 관리하는데 그 제어의 역전을 구현하기 위해 사용하는 방법
: ~한 클래스가 ~한 다른 클래스에 의존한다
: 스프링 컨테이너가 B 객체를 만들어서 클래스 A에 준다
@Autowired
를 통해 빈을 주입(빈은 스프링 컨테이너에서 관리하는 객체다)
public class A {
// A에서 B를 주입받음
@Autowired
B b;
}
스프링은 스프링 컨테이너를 제공해 빈을 생성하고 관리한다
빈이란?
: 스프링 컨테이너가 생성하고 관리하는 객체(앞 예시의 B), 스프링은 빈을 스프링 컨테이너 등록을 위해서 XML파일 설정, 애너테이션 추가 등 방법을 제공함(빈 동록에도 여러 가지 방법이 있다)
@Component // 클래스 MyBean 빈으로 등록
public class MyBean {}
@Componet 애너테이션을 붙이면 MyBean클래스가 빈으로 등록됨
스프링 컨테이너에서 빈으로 관리되며 이름은 클래스의 이름 첫글자를 소문자로 myBean이 됨
AOP(Aspect Oriented Progeramming, 관점 지향 프로그래밍)
: 프로그래밍에 대한 관심을 핵심 관점, 부가 관점으로 나누어서 관심 기준 모듈화
예시
계자 이체, 고객 관리 프로그램에 있어서 각 프로그램 로깅 로직(벌어진일 기록 로직),여러 데이터 관리
위한 DB연결 로직이 포함됨
핵심 관점 : 계좌이체, 고객 관리 로직
부가 관점 : 로깅, DB연결 로직
여기서 부가 관점 해당 로직 모듈화해 앞 그림과 같이 개발할 수 있게 해줌(분리)
PSA(Portable Service Abstraction, 이식 가능한 서비스 추상화)
: 스프링에서 제공하는 다양한 기술들을 추상화해 개발자가 쉽게 사용하는 인터페이스, 클라이언트의 매핑과 클래스, 메서드의 매핑을 위한 애너테이션
스프링에서 데이터베이스 접근하기 위한 기술로 JPA, MyBatis, JDBC가 있음
어떤 기술을 사용하든 일관된 방식으로 데이터베이스에 접근하도록 인터페이스를 지원 또는
WAS, PSA의 예시와도 같이 코드는 그대로 두되 WAS를 톰캣이 아닌 언더토우, 네티와 같은 곳에서도 코드 그대로 사용
스프링 부트 스타터
스타터는 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를 더 쉽게 사용하기 위한 의존성 모음 |
자동 구성
스프링에서는 내가 구성하지 않은 부분이어도 자동으로 어떻게 구성하는 경우가 있다
스프링 부트는 서버를 시작할 때 구성 파일을 읽어와서 설정한다. 이를 자동 설정이라 한다spring-boot-autoconfigure/spring.factories
검색으로 프로젝트에 쓰일 자동 구성 후보들 찾을 수 있다
자바 버전
스프링 부트 2는 자바 8 버전 이상을 사용
스프링 부트 3은 자바 17 버전 이상을 사용(+텍스트 블록, 레코드, 패턴 매칭)
- 텍스트 블록
"SELECT * FROM \ "items" \n " + "WHRER" -> (스프링 부트 3) """SELECT * FROM "items" WHERE ~~";
이전에는 여러 줄의 텍스트를 작성하려면 \n를 추가해야 했지만 이제는 ""로 감싼 텍스트를 사용해 여러 줄을 표현한다 - formatted() 메서드
값 파싱을 위한 formatted() 메서드 제공 String textBlock17 = """ { "id" : %d" "name" : %s, } """.formatted(2, "juice"); - 레코드
데이터 전달을 목적으로 객체를 더 빠르고 간편하게 만들기 위한 기능. 레코드는 상속할 수 없으며 파라미터 정의한 필드는 private final로 정의, 레코드는 게터(getter)를 자동으로 만들어 애너테이션이나 메서드로 게터 정의 안 해도 됨
recod Item(String name, int price) {
// 이렇게 할 시 파라미터가 private final로 정의됨
}
Item juice = new Item("juice", 3000);
juice.price(); // 3000
```
- 패턴 매칭
타입 확인을 위해 사용하던 instanceof 키워드를 조금 더 쉽게 사용할 수 있게 해 준다 이전에는 instanceof 키워드와 형변환 코드를 조합해야 했다면 이제는 바로 형변환 한다 // 11 버전 if (o instanceof Integer) { Integer i = (Integer) o; } // 17 버전 if (o instanceof Integer i) { ... }
- 자료형에 맞는 case 처리
switch-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로 대체
스프링 부트 2에서 패키지 네임스페이스가 jakarata.* 에서 -> (스프링 부트3)javax.* 로 변경됨
- GraalVM 기반의 스프링 네이티브 공식 지원
3.0부터 GraalVM 네이티브 이미지 지원. 기존 사용하던 자바 가상 머신에 비해 훨씬 빠르게 시작, 더 적은 메모리 공간 차지, JVM 실행 파일과 비교해 네이티브 이미지 사용하면 가동 시잔 짧아지고 메모리 더 적게 소모
더 자세한 GraalVM제공 네이티브 이미지에 대한 설명은 https://mangkyu.tistory.com/302 망나니 개발자님 블로그에 잘 설명해 놓으셨다
스프링 부트 3 코드 이해하기
@SpringBootApplication
public class SpringBootDeveloperApplication {
public static void main(String[] args) {
SpringApplication.run(SpringBootDeveloperApplication.class, args);
}
}
main() 메서드와
같은 역할로 여기서 스프링 부트가 시작됨 @SpringBootApplication
애너테이션을 추가하면 스프링 부트 사용에 필요한 기본 설정을 해줌 SpringBootApplication.run()
메서드는 애플리케이션 실행
첫 인수는 스프링 부트 3 애플리케이션의 메인 클래스로 사용할 클래스(자바의 Main()
), 두 번째 인수는 커맨드 라인의 인수들 전달
@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 {
...
}
여기서 가장 큰 애너테이션 3가지
@SpringBootConfiguration
스프링 부트 관련 설정. @Configuration을 상속해서 만든 애너테이션으로 개발자가 직접 사용하진 않지만
스프링 부트 3이전에 사용했음
@ComponentScan
사용자가 등록한 빈을 읽고 등록. @Component 애너테이션을 가진 클래스들을 찾아 빈으로 등록.
but 모든 빈에 @Component만 사용하지는 않는다, 이것을 감싸는 애너테이션이 여러개 있으며 용도에 따라
다른 애너테이션을 많이 사용한다
애너테이션명 | 설명 |
@Configuration | 설정 파일 등록 |
@Repository | ORM 매핑 |
@Controller, @RestController | 라우터 |
@Service | 비즈니스 로직 |
@EnableAutoConfiguration
자동 구성 활성화. 스프링 부트 서버 실행때, 메타 파일 읽고 정의된 설정들 자동으로 구성
spring.factories 같은 파일클래스가 애너테이션 사용할때 자동 설정됨
스프링 컨테이너의 빈 관리
@RestController
public class TestController {
@GetMapping("/test") // -> /test Get 요청에 따른 test()메서드 실행
public String test() {
return "Hello, world!";
}
}
@RestController는 라우터 역할로 /test Get요청이 오면 test() 메서드 실행을 위해 구성
@RestController는 @Component와 용어가 다르지만 @RestController의 내부 애너테이션을 보면
@Controller + @ResponseBody 합쳐진 것인데. 그 안의 @Controller의 내부 애너테이션을 또 살펴보면
@Component가 있다
앞서 설명한 애너테이션과 @RestController는 @Component 애너테이션을 포함함으로 역할에 따라 명확히
다른이름을 쓸 수 있다
라우터 : HTTP 요청과 메서드를 연결하는 장치. 이것이 있어야지만 클라이언트의 요청에 맞는 메서드 실행가능
스프링 부트 3 구조 이해하기
- 프레젠테이션 계층
HTTP 요청을 받고 이 요청을 비즈니스 계층으로 전송하는 역할, 컨트롤러가 프레젠테이션 계층의 역할
- 비즈니스 계층
서비스를 만들기 위한 로직
웹 사이트에서 벌어지는 모든 작업(주문 서비스, 주문 개수, 가격)
- 퍼시스턴스 계층
모든 데이터베이스 관련 로직 처리
계층은 개념의 영역이고, 컨트롤러, 서비스, 리포지토리는 실제 구현을 위한 영역이다
Ioc
자바에서 new연산자 통해 메모리 올라감 → 자바 프로그램 죽는 순간 같이 죽게 됨
(책 설명에서는 Ioc도 외부에서 객체를 가져와서 사용, DI도 외부에서 객체를 가져온다)
(한번 코드 짜보고 그림으로 그려보기)
제어의 역전 내가 제어해야 하는 것처럼 jvm 컨트롤러
프레임 워크에게 내 역할(제어)를 위임해서 사용
객체 관리를 ‘내’가 하는 것이 아닌?
Q. 부트 구조에서 계층이 3가지로 나뉘는데 계속 3가지로 나뉘어져 있는가?
A. 하나의 계층이 없어도 작동할 수 있다(통상적인 규격이라 봐도 됨, 데이터의 흐름만 맞다면 잘 작동한다)
컨트롤러 ->레포지토리 바로 해도 잘 작동
참조
'TIL > SprintBoot3 백엔드 개발자되기 Study' 카테고리의 다른 글
1. 자바 백엔드 개발자가 알아두면 좋은 지식 (0) | 2023.11.08 |
---|