스프링 부트 시작할 때 주의사항
- Java를 기반으로 한 웹 프레임워크다.
- 오픈소스 기반 프레임워크다.
- SpringBoot는 IoC 컨테이너를 가진다.
IoC(Inversion of Control, 제어의 역)이란 개발자가 인스턴스를 생성해서 직접 Heap 메모리 영역에 올리는 것이 아니라 SpringBoot가 알아서 메모리 영역을 관리하는 것을 말한다. 개발자가 스스로 올린게 아니지만, 이미 메모리 영역에 올라가 있는 것이다. - SpringBoot는 DI를 지원한다.
DI(Dependency Injection, 의존성 주입)은 객체를 생성하고 한번 생성된 객체를 여러 클래스에서 공유하여 사용할 수 있는 것이다. - SpringBoot는 많은 필터를 가진다.
탐캣 내에 존재하는 스프링 컨테이너에 들어가는 필터를 가지고 있다. AOP 인터셉터도 필터의 개념이다. - 스프링은 어노테이션을 가지고 있다.
컴파일러가 주석은 무시하지만 어노테이션은 참고해서 컴파일 한다. 예를 들어 @Autowired는 로딩된 객체를 이미 존재하는 변수에 집어넣어라는 뜻이다. 특정 클래스 내에 있는 어노테이션, 메서드, 필드를 런타임시 체크하는 것이 리플렉션이다. - MessageConverter를 가지고 있다.
객체간 통신할 때 JSON 형식의 데이터를 가지고 통신한다. 스프링에서는 MessageConverter(jackson) 라이브러리를 사용해서 객체간 통신하게 된다. - BufferedReader && BufferedWriter를 사용한다.
8bit로 구성된 1Byte로 통신할 때 수신측에서 1Byte로 나눠서 읽기에는 비효율적이다. 자바에서는 InputStreamReader로 데이터를 읽어들인다. 이 때 배열로 받아오면 배열의 길이를 정해줘야 하기 때문에 비효율적이다. 이런 상황에서 사용하는 방법이 BufferedReader를 쓴다. 전송데이터인 Byte Stream을 가변길이로 쓰기 위해서 BufferedReader/BufferedWriter를 사용한다. 어노테이션으로는 @ResponseBody(BufferedWriter) / @RequestBody(BufferedReader)를 사용한다. - JPA를 사용한다.
SQL문과 Spring framework와의 인터페이스를 제공하는 것이 JPA(Java Persistence API)다. 기존 EJB에서 제공되던 엔터티 빈을 대체하는 기술이다. JPA는 OOP 관점에서 데이터 모델링을 하게 해준다. - 서블릿 컨테이너를 사용한다.
서블릿 컨테이너는 탐캣을 의미한다. URL은 자원을 요청할 때 사용한다. URI는 식별자를 통해서 request를 날린다. 최초 요청이 들어오면 서블릿 객체(init())를 생성한다. 두번째 요청 시 이미 생성된 서블릿 객체를 사용한다.request가 처음 들어와서 new aaa() 객체를 생성하게 되면 heap 메모리 영역에 객체가 올라간다. 이 후 특정 클래스 내의 메소드를 호출하게 되면 독립적인 메소드 공간이 스택 메모리에 올라가게 된다. 여러명의 유저가 동시에 메소드를 호출하면 여러개의 독립적인 메소드 공간이 스택메모리에 올라가게 된다. 만약 메소드 호출을 스레드로 관리한다고 하면 서블릿 객체는 재사용되고 기존에 설정된 스레드 개수가 넘어가면 나머지 사용자들은 대기하게 된다. - Bean을 사용한다.
스프링에서 IoC 컨테이너가 관리하는 객체를 Bean 객체라 한다. Bean 객체만 의존성 주입을 받게 된다. applicationContext에서 가져온 객체가 Bean 객체다.
웹서비스 작동하는 원리(스프링 부트 사용)
MVC 디자인 패턴
스프링 부트는 MVC 디자인 패턴을 사용한다. data를 담당하는 Model과 HTML를 사용해서 프론트 영역을 표현하는 View 영역과 서버에서 데이터를 처리/연산하는 Controller로 구분된다. 만약 IntelliJ를 통해서 스프링 부트 프로젝트를 개발한다면 thymeleaf 보다는 mustache가 낫다. IntelliJ community 버전에서는 themeleaf 지원을 안한다.
서버 데이터 흐름(dto)
CRUD 작동을 위해서는 폼 데이터를 받아와서 서버에서 DB와의 연결을 확립해야 한다. form 데이터를 controller에서 받는 과정은 dto 객체를 통해서 받게 된다. DTO(Data Transfer Object)란 서로다른 계층 간 데이터를 교환하기 위해서 사용되는 객체다. dto 객체는 로직을 가지지 않으며 순수한 데이터 객체(Getter / Setter만 가지는 클래스) 다.
참고로 JAVA에서 Setter와 Getter란 외부에서 객체에 접근해서 필드값(변수값)을 임의로 변경하지 못하게 막는 방법이다. 객체 내 필드값을 무작위로 변경한다면 객체의 무결성(Integrity)가 깨지기 때문에, 반드시 Getter/Setter 메소드를 통해서 변경하는 것이 안전하다.
JPA 사용
Java Persistence API는 데이터베이스 SQL 문과 JAVA Spring Boot를 연결해주는 인터페이스다. JPA는 Entity와 Repository 2개의 핵심 기능을 가지고 있다. Entity란 Database가 이해할 수 있는 규격화된 데이터 형식을 의미한다. Entity가 Database로 이동하는 기능을 담당하는 것이 Repository다. Repository는 interface로 만든다. JPA에서는 이미 CrudRepository interface가 있기 때문에 그대로 사용하면 된다.
dto로 받은 데이터를 DB에 저장하기 위해서는 Entity로 변환해줘야 한다.
Entity.java
package com.example.firstProject.entity;
import lombok.AllArgsConstructor;
import lombok.ToString;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
@Entity //DB가 해당 객체를 인식 가능
@AllArgsConstructor
@ToString
public class Article {
@Id
@GeneratedValue
private Long id;
@Column
private String title;
@Column
private String content;
}
Contoller.java
controller에서 dto를 Entity 객체로 변환시켜 준다. @Autowired는 heap 메모리에 올라가있는 기존에 존재하는 객체에 Spring Boot가 자동으로 객체를 연결해준다. 이걸 의존성주입(DI, Dependency Injection)이라 한다.
package com.example.firstProject.controller;
import com.example.firstProject.dto.ArticleForm;
import com.example.firstProject.entity.Article;
import com.example.firstProject.repository.ArticleRepository;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
@Controller
@Slf4j
public class ArticleController {
@Autowired // 스프링 부트가 만든 객체를 자동으로 연결해준다.의존성 주입)
private ArticleRepository articleRepository;
@GetMapping("/articles/new")
public String articlesMethod(){
return "articles/new";
}
@PostMapping("/articles/create")
public String createArticles(ArticleForm form){
log.info(form.toString());
// System.out.println(form.toString());
// 1.DTO를 Entity로 변환해야 함
// to.Entity() 메소드는 Form에서 작성해줌
Article article = form.toEntity();
log.info(article.toString());
// System.out.println(article.toString());-> 로깅으로 대체
// 2. Repository에게 Entity를 DB에 저장하게 함
Article saved = articleRepository.save(article);
log.info(saved.toString());
// System.out.println(saved.toString());
return "";
}
}
Repository interface
Spring Boot에서 제공해주는 CrudRepository를 상속받아 save() 메소드를 controller에서 사용할 수 있게 된다.
package com.example.firstProject.repository;
import com.example.firstProject.entity.Article;
import org.springframework.data.repository.CrudRepository;
public interface ArticleRepository extends CrudRepository<Article, Long> {
}
'Programming' 카테고리의 다른 글
Kotlin Hello World 출력하기 (0) | 2022.03.07 |
---|---|
Spring Boot 어노테이션 모음집 (0) | 2022.03.01 |
JAVA 오버로딩 오버라이딩이란 추상클래스 구현이란 인터페이스란 객체지향 기술 종류 (0) | 2022.02.25 |
JAVA StringTokenizer 란 개념 이용방법 (1) | 2022.02.23 |
JAVA BufferedReader와 BufferedWriter 사용법 (0) | 2022.02.18 |
JAVA StringBuilder란? StringBuffer란? 차이점 및 사용하는 이유 (0) | 2022.02.17 |
댓글