-
스프링부트 3 백엔드 개발자 되기 : 시작하는 과정 (2)Programming/JAVA 2023. 8. 17. 16:23
( 60p ) 2.3.4 스프링 부트 3과 자바 버전
스프링부트 3 이전과 이후는 사용할 수 있는 자바 버전 범위가 다르다.
스프링 부트 2는 자바 8버전 이상
스프링 부트 3은 자바 17버전 이상자바 17버전 주요 변화
: 텍스트 블록, 레코드, 패턴 매칭 등
(1) 텍스트 블록
이전에는 여러 줄의 텍스트를 작성하려면 \n 을 추가해야했지만, 이제는 " " " 로 감싼 텍스트 사용해 여러 줄의 텍스트를표현할 수 있다. ( 가독성 좋아짐 )
(2) formatted() 메서드
또한 값을 파싱하기 위한 formatted() 메서드도 제공
이 기능이 없었을 때는 매우 불편한 방법으로 값 파싱
ex ) String textBlock17 = ''' { "id" : %d "name" : %s, } '''.formatted(2,"juice");(3) 레코드
레코드는 데이터 전달을 목적으로 하는 객체를 더 빠르고 간편하게 만들기 위한 기능이다. 레코드는 상속을 할 수 없고 파라미터에 정의한 필드는 private final 로 정의된다. 또한 레코드는 게터를 자동으로 만들기 때문에 어노테이션이나 메서드로 게터 정의 하지 않아도 된다.
ex ) record Item(String name, int price) { } // 이렇게 하면 파라미터가 private final로 정의
Item jice = new Item("jice", 3000);
juice.price(); //3000더보기* 여기서 final 은 자바 키워드 : 내부 클래스에서 외부의 변수를 사용할 때 외부 변수는 반드시 final로 선언해 줘야 한다. 불변성을 얻게 되어 실행 중 객체가 변하는 것을 막을 수 있고, 이로 인한 오류 방지
* final : 클래스나 변수에 final을 붙이면 처음 정의된 상태가 변하지 않는 것을 보장한다는 의미이다. Java에서 변수들은 기본적으로 가변적인데, 변수에 final 키워드를 붙여 참조값을 변경 못하도록 해 불변성을 확보할 수 있다.
IoC를 통한 DI를 받는 방법은 @Autowired를 통한 방법과 생성자를 기반으로 받을 수 있다.
@RequiredConstructor를 통해(혹은 그냥 생성자를 통해) private final Repository repository와 같이 주입을 받게 되면 불변성을 얻게 되어 실행 중 객체가 변하는 것을 막을 수 있고 이로 인해 오류를 방지할 수 있다.
코드의 품질도 높아지며 순환 참조를 방지하는 등의 부가적인 이득도 있다.
Autowired를 지양하고 private final을 생성자로 생성하도록 하자.(4) 패턴 매칭
타입 확인을 위해 사용하던 instanceof 키워드를 좀 더 쉽게 사용할 수 있게 한다. 이전에는 instanceof 와 형변환 코드를 조합해야 했지만, 이제는 바로 형변환을 한다음 사용할 수 있다.
ex ) 이전 if(o instanceof Integer){ Integer i = (integer) o;}
이후 if(o instanceof Integer){ }(5) 자료형에 맞는 case 처리
switch-case 문으로 자료형에 맞게 case 처리할 수 있음
ex ) return switch(o) {
case Double d -> d.intValue();
case Float f -> d.intValue();
case String s -> Integer.parseInt(s);
default -> 0d;
}(6) Servlet, JPA 의 네임 스페이스가 Jakarta 로 대체
패키지 네임스페이스가 javax.* 에서 jakarta.*로 변경되었다. 만약 스프링 부트2 버전을 사용하고 있다면 패키지 이름을 javax에서 jakarta 를 사용하게 변경해야 한다.
(7) GraalVM 기반의 스프링 네이티브 공식 지원
스프링 어플리케이션을 네이티브 이미지로 컴파일해 JVM에 구동되는 어플리케이션에 비해 시작 시간과 메모리 오버 헤드를 줄일 GraalVM 기반의 스프링 네이티브를 공식 지원. JVM 실행 파일과 비교해 네이티브 이미지를 사용하면 가동시간이 짧아지고 메모리를 더 적게 소모한다.
2.4 스프링부트 3 코드 이해하기
2.4.1 @SpringBootApplication 이해하기
SpringBootDeveloperApplication.java
- 이 클래스는 자바의 main() 메서드와 같은 역할
- 여기서 스프링 부트 시작
- @SpringBootApplication 어노테이션 추가 ( 스프링 부트 핵심 어노테이션 )
= 스프링 부트 사용에 필요한 기본 설정
- SpringApplication.run( 메인클래스로 사용할 클래스, 커맨드 라인의 인수들 args) 메서드는 어플리케이션 실행@SpringBootApplication 파헤치기
@SpringBootConfiguration : 스프링 부트 관련 설정을 나타내는 어노테이션, 스프링 아는 독자라면 Configuration 을 상속해서 만든 어노테이션, 개발자가 직접 사용하는 것은 아니.
@ComponentScan : 사용자가 등록한 빈(컴포넌트)를 읽고 등록하는 어노테이션, @Component라는 어노테이션 가진 클래스들을 찾아 빈으로 등록하는 역할 그렇다고 모든 빈에 @Component만 사용하는 것은 아님. @Component 를 감싸는 어노테이션이 있는데 실제 개발을 하면 @Component 어노테이션보다는 용도에 따라 다른 어노테이션 사용하므로 아래의 어노테이션은 미리 눈에 익히고 넘어갈 것.
- @Configurateion : 설정 파일 등록
- @Repository : ORM 매핑
- @Controller, @RestController : 라우터
- @Service : 비지니스 로직* ORM : Object Relational Mapping(객체-관계-매핑), 객체와 DB관계를 매핑해주는 도구
@EnableAutoConfiguration : 스프링부트에서 자동 구성을 활성화하는 어노테이션,
스프링 부트 서버가 실행될 때 스프링 부트의 메타 파일을 읽고 정의된 설정들을 자동으로 구성하는 역할 수행
'자동 구성'에서의 spring.factories 파일에 클래스들이 모두 @EnableAutoConfiguration을 사용할 때 자동 설정된다.2.4.2 테스트 컨트롤러 살펴보기
앞에서 스프링 컨테이너가 빈을 관리한다. 실제로 작성한 TestController.java 파일 살펴보며 빈이 어떻게 등록되는지 확인.
@RestController : 라우터 역할을 하는 어노테이션
이 어노테이션이 있어야 클라이언트 요청에 맞는 메서드를 실행할 수 있음
현재 TestController를 라우터로 지정해 GET요청이 왔을 때 test() 메서드를 실행하도록 구성.
* 라우터 : HTTP 요청, 메서드 를 연결하는 장치@RestController - @Controller - @Component
그래서 @ComponentScan 을 통해 빈으로 등록되고 있었던 것. 빈이 무슨 역할을 하는지 명확하게 구분하기 위해 같은 Component지만, Repository, Service, Configuration 처럼 다른 이름으로 구분.3장 스프링 부트 3 구조 이해하기
스프링부트 3구조 살펴보기 > 스프링부트3 프로젝트 발전시키기 > 스프링부트 요청,응답 과정 한 방에 이해하기
# 프레젠테이션 계층 # 비지니스 계층 # 퍼시스턴스 계층3.1 스프링 부트 3 구조 살펴보기
스프링 부트는 각 계층이 양 옆의 계층과 통신하는 구조
* 계층 : 각자의 역할과 책임이 있는 어떤 소프트웨어의 구성 요소
각 계층은 서로 소통할 수 있지만, 다른 계층에 직접 간섭하거나 영향을 미치지 않음3.1.1 카페와 빵집으로 이해하는 계층
카페와 빵집의 협업(소통), 알바생이 바뀐다든지 직접 간섭이나 영향은 없음.
각 계층은 자신의 책임에 맞는 역할을 수행하며 필요에 따라 소통한다.프레젠테이션계층(컨트롤러) - 비지니스계층(서비스) - 퍼시스턴스 계층(리포지토리) - 데이터베이스
persistence 영속성(데이터의 속성)1. 프레젠테이션 계층 ( 컨트롤러 )
: HTTP 요청을 받고 이 요청을 비지니스 계층으로 전송하는 역할
컨트롤러가 바로 프레젠테이션 계층의 역할, TestController 클래스와 같은 것
컨트롤러는 스프링 부트 내에 여러 개 있을 수 있음2. 비지니스 계층 ( 서비스 )
: 모든 비지니스 로직 처리 ( 서비스를 만들기 위한 로직 = 비지니스 로직 )
웹 사이트에서 벌어지는 모든 작업, 주문 서비스라면 주문 개수, 가격 등의 데이터 처리하기 위한 로직, 주문 처리를 하다가 발생하는 예외처리 로직, 주뭉늘 받거나 취소하는 것처럼 프로세스를 구현하기 위한 로직 등.3. 퍼시스턴스 계층 ( 레포지토리 )
: 모든 데이터베이스 관련 로직 처리, 이 과정에서 데이터베이스에 접근하는 DAO 객체를 사용할 수 있음
DAO : 데이터베이스 계층과 상호작용하기 위한 객체계층은 개념의 영역이고, 컨트롤러, 서비스, 리포지토리는 실제 구현을 위한 영역
3.1.2 스프링 부트 프로젝트 디렉토리 구성하며 살펴보기
정해진 프로젝트 구조는 없지만, 추천 프로젝트 구조가 있음.
- main : 실제 코드를 작성하는 공간, 프로젝트 시해에 필요한 소스 코드나 리소스 파일은 모두 이 폴더 안에 들어 있음
- test : 프로젝트의 소스 코드를 테스트할 목적의 코드나 리소스 파일이 들어 있음
- build.gradle : 빌드 설정하는 파일, 의존성이나 플러그인 설정 등과 같이 빌드에 필요한 설정을 할 떄 사용
- setting.gradle : 빌드할 프로젝트의 정보를 설정하는 파일3.1.3 main 디렉토리 구성하기
resources 폴더 아래 templates, static 디렉토리, application.yml (스프링 부트 설정)파일 생성
application.yml 파일은 스프링 부트 서버가 실행되면 자동으로 로딩되는 파일.3.2 스프링 부트 3 프로젝트 발전시키기
의존성을 추가한 다음, 프레젠테이션 계층, 비지니스 계층, 퍼시스턴스 계층 순서대로 코드 추가
3.2.1 build.gradle 에 의존성 추가하기
01. 의존성 추가
스프링부트용 JPA 인 스프링 데이터 JPA,
로컬 환경과 테스트 환경에서 사용할 인메모리 데이터베이스인 H2,
반복 메서드 작성 작업을 줄여주는 라이브러리 롬복 추가02. Gradle 탭에서 새로고침 버튼 누르면 추가한 의존성 다운로드 가능
3.2.2 프레젠테이션, 서비스, 퍼시스턴스 계층 만들기
01. 프레젠테이션 계층에 속하는 컨트롤러 관련 코드 작성
TestController.java 에서 test() 메서드 삭제하고 새 코드 추가@RestController
public class TestController {
@Autowired / / TestService 빈 주입
TestService testService;@GetMapping("/test")
public List<Member> getAllMembers(){
List <Member> members = testService.getAllMembers();
return members;
}
}02. 비지니스 계층 서비스 코드 작성 TestController.java파일과 같은 위치에
TestService.java 파일 생성@Service
public class TestService {@Autowired
MemberRepository memberRepository; // 1 빈 주입@public List<Member> getAllMembers() {
return memberRepository.findAll(); // 2 멤버 목록 얻기
}
}1. 멤버리포지토리라는 빈 주입 받은 후에
2. findALl() 메서드를 호출해 멤버테이블에 저장된 멤버 목록을 모두 가져온다03. 퍼시스턴트 계층 코드 작성
DB에 접근할 때 사용할 객체인 Member DAO 를 생성하고 실제 DB에 접근하는 코드 작성, 같은 위치에
Member.java 파일 생성해 다음과 같이 코드 작성package me.grace.springbootdeveloper; import jakarta.persistence.*; import lombok.AccessLevel; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.NoArgsConstructor; @NoArgsConstructor(access= AccessLevel.PROTECTED) @AllArgsConstructor @Getter @Entity public class Member {//DAO 생성, DB에 접근하는 코드 @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id", updatable =false) private Long id; //DB 테이블의 id 컬럼과 매칭 @Column(name="name", nullable=false) private String name; //DB 테이블의 name 컬럼과 매칭 }
위는 member라는 이름의 테이블에 접근하는 데 사용할 객체
04. 인터페이스 파일 MdmberRepository.java 생성해 코드 작성
( member 테이블과 Member 클래스를 매핑하는 코드 작성, 매핑 작업에는 인터페이스 파일 필요 )
DB에서 데이터 가져오는 퍼시스턴트 계층 역할 ,
member라는 이름의 테이블에 접근해서 Member 클래스에 매핑하는 구현체(인터페이스)@Repository public interface MemberRepository extends JpaRepository<Member, Long> { }
** import error 처리
1. error 부분 클릭해 ALT + ENTER3.2.4 작동 확인하기
보통 실행 테스트 하기 위해 어플리케이션 실행할 떄마다 SQL문을 실행해 데이터베이스에 직접 데이터를 넣는데, 현재는 인메모리 데이터베이스 사용하고 있기 때문에 어플리케이션을 새로 실행할 때마다 데이터가 사라져 매우 불편하다.이를 해결하기 위해 어플리케이션을 실행할 때 원하는 데이터를 자동으로 넣는 작업을 한다.
01 어플리케이션이 실행될 때 저장할 더미 데이터를 넣을 SQL 파일을 생성한다. resources 디렉터리에 data.sql 파일
INSERT INTO member (id, name) VALUES (1, 'name 1') INSERT INTO member (id, name) VALUES (1, 'name 2') INSERT INTO member (id, name) VALUES (1, 'name 3')
02 기존의 application.yml 파일 코드 변경
show-sql, format_sql 옵션은 어플리케이션 실행 과정에 데이터베이스에 쿼리를 할 일이 있으면 실행 구문을 모두 보여줌
defer-datasource-initialization 옵션은 어플리케이션 실행시 테이블 생성하고 data.sql 파일의 쿼리 실행 옵션
모두 작성 후 SpringBootDeveloperApplication.java 파일 탭 누르다음 재실행 아이콘 클릭spring: jpa: # 전송 쿼리 확인 show-sql : true properties: hibernate: format_sql: true #테이블 새성 후에 data.sql 실행 defer-datasource-initialization: true
03 콘솔창에서 CTRL + F 누르고 CREATE TABLE 검색해 테이블이 잘 만들어졌는지 확인
04 포스트맨으로 HTTP 요청 시도
포스트맨을 켜고 HTTP 메서드를 GET으로, URL 에 http://localhost:8080/test 입력,
Send 버튼 눌러 스프링 부트 서버에 HTTP 요청 전송
- data.sql 파일로 작성해 저장한 데이터를 포스트맨, 즉, 클라이언트에서 확인 가능포스트맨에서 데이터를 보기까지 다음과 같은 과정 거친다.
HTTP 요청( url: /test) > TestController 프레젠테이션 계층 > TestService 비지니스 계층 > MemberRepository 퍼시스턴스 계층 > DB
1. 포스트맨에서 톰캣에 /test GET 요청, 이 요청은 스프링 부트 내로 이동함
2. 스프링 부트의 디스패처 서블릿이라는 녀석이 URL 분석하고 이 요청을 처리할 수 있는 컨트롤러 찾고 전달
3. /test GET 요청을 처리할 수 있는 getAllMembers()메서드와 요청이 매치, 메서드에는 비지니스 계층과 퍼시스턴스 계층을 통하면서 필요한 데이터 가져옴.
4. 뷰 리졸버는 템플릿 엔진을 사용해 HTML 문서를 만들거나 JSON, XML 등의 데이터 생성해 ( 톰캣으로 )
5. members 를 return하고 그 데이터를 포스트맨에서 볼 수 있게 됨 ( 톰캣에서 포스트맨으로 )핵심 요약
1. 프레젠테이션 계층은 HTTP 요청을 받고 비지니스 계층으로 전송
2. 비지니스 계층은 모든 비지니스 로직 처리, 퍼시스턴스 계층에서 제공하는 서비스를 사용할수도 있고, 권한을 부여하거나 유효성 검사를 하기도 함
3. 퍼시스턴스 계층은 모든 스토리지 관련 로직 처리, 이 과정에서 데이터베이스에 접근하기 위한 객체인 DAO 사용할 수 있음참조
'Programming > JAVA' 카테고리의 다른 글
스프링부트 프로젝트 게시판 (0) 2023.05.27 [ JavaSpring ]Whitelabel Error Page 해결방법 (0) 2023.04.28 [ JavaSpring ] Hello world 출력 (0) 2023.04.28 JAVA (0) 2022.09.13 JSP 게시판 만들기 강좌 -6강 (0) 2022.09.13