스프링 부트의 필요성
스프링 부트를 이해하려면 먼저 "왜" 쓰는지를 이해해야 합니다.
그래서 이번 블로깅을 통해서는 WHY에 대해 알아보도록 하겠습니다.
스프링 부트의 특징
- 내장 서버를 이용해 별도의 설정 없이 독립 실행이 가능한 스프링 애플리케이션
- 톰캣, 제티와 같은 웹 애플리케이션 서버 자체 내장
- 빌드 구성을 단순화 하기위한 Spring Boot Starter 의존성 제공
- XML 설정 없이 단순 자바 수준의 설정 방식 제공
- JAR 이용해 자바 옵션만으로 배포 가능
- 애플리케이션의 모니터링 관리를 위한 스프링 액추에이터 제공
위와 같은 여섯가지 장점이 있습니다.
이 장점들에 대해 알아보겠습니다.
WAS(Web Application Server ) 란?
웹 서버 + 웹 컨테이너입니다.
웹 컨테이너는 JSP와 Servlet 을 실행시킬 수 있는 환경으로 데이터를 동적으로 처리하는 부분입니다.
웹 서버는 클라이언트에게 데이터를 요청 받으면 컨테이너로 전송하여 데이터를 처리하는 정적인 데이터를 처리하는 부분입니다.
이러한 WAS 는 대표적으로 tomcat이 있습니다.
톰캣은 jsp, asp, php 등 개발 언어를 읽고 컨텐츠를 동적으로 처리하고, 서비스를 처리할 수 있게 해줍니다.
이러한 톰캣은 포트설정/ 서블릿 경로설정 / 라이브러리 환경 등 내부적으로 설정해야하는 부분이 많습니다.
그래서 스프링 부트가 WAS가 가진 내장 서버 때문에 별도의 내장 서버 설정을 안해도 된다는 것은 큰 장점입니다.
스프링 부트 스타터 의존성 제공이란?
스프링 부트에서 스타터란 설정을 자동화해주는 모듈입니다.
이는 프로젝트에서 설정해줘야하는 다양한 의존성을 사전에 미리 제공해준다는 것을 의미합니다.
이 기능의 큰 예시로 라이브러리를 보면 알 수 있습니다.
스프링 부트에선 Thymeleaf, lombok, Spring Web 등 많은 라이브러리를 코드 한 줄로 추가하여 사용할 수 있습니다.
실제 이러한 라이브러리를 사용하기 위해서는 이와 연관되어 있는 많은 라이브러리를 직접 추가해줘야합니다.
그리고 라이브러리의 버젼을 쉽게 변경하고 적용할 수 있습니다.
- 메이븐 환경 : pom.xml 수정
- 그레들 환경 : build.gradle 수정
XML 설정 없이 자바 수준 설정 방식이 왜 장점인가?
XML은 많은 태그를 가지고 있어 가독성이 떨어진다는 단점이 있습니다.
그래서 만약 문법을 잘못 작성하여 에러가 발생하면 그 원인을 찾기 힘듭니다.
web.xml의 servlet 설정을 예를 들어 보겠습니다.
servlet, servlet-mapping 등 각각의 순서를 맞춰야 하며 내부 코드에서 오타가 발생한다고 해도
에러가 친절히 나오는 것도 아닌 무슨 의미인지 모를 에러가 발생합니다.
이러한 설정들을 자바 코드로 클래스 단위로 설정하여 쉽게 관리할 수 있다는 장점이 있습니다.
스프링 액추에이터
서비스가 정상적으로 동작하고 있는지를 모니터링 해줍니다.
서비스는 개발 단계만큼 운영 단계가 중요합니다.
이러한 운영 단계에서 배포에 장애가 있고, 잘 동작하는지 확인해준다는 의미입니다.
스프링 프레임워크
- 객체지향 설계원칙에 맞는 재사용과 확장이 가능한 애플리케이션 개발 스킬 향상
- 보다 나은 성능과 서비스의 안전성이 필요한 복잡한 기업용 엔터프라이즈 시스템 구축 능력
스프렝 프레임워크를 학습한다면 위 두가지를 배울 수 있습니다.
스프링 프레임워크를 줄여서 보통 스프링이라고 부릅니다.
스프링을 배우는 이유를 과거의 JSP 를 사용하던 시절과 비교해 보겠습니다.
- 과거 JSP 를 사용하던 시기
JSP 개발 방식은 사용자에게 보여지는 View 페이지쪽 코드와 사용자의 요청을 처리하는 서버쪽 코드가 섞여 있는 형태의 개발 방식입니다.
쉽게 말해서 [ 웹 브라우저를 통해서 사용자에게 보여지는 HTML/JS 코드 ] 와 [ 사용자의 요청을 처리하는 서버의 Java 코드 ] 가 섞여 있습니다.
예를 들어 보겠습니다.
<%@ page contentType="text/html;charset=UTF-8" language="java" %>
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<%@ taglib uri="http://java.sun.com/jsp/jstl/functions" prefix="fn" %>
<!-- (1) 시작 -->
<%
request.setCharacterEncoding("UTF-8");
response.setContentType("text/html;charset=UTF-8");
System.out.println("Hello Servlet doPost!");
String todoName = request.getParameter("todoName");
String todoDate = request.getParameter("todoDate");
ToDo.todoList.add(new ToDo(todoName, todoDate));
RequestDispatcher dispatcher = request.getRequestDispatcher("/todo_model1.jsp");
request.setAttribute("todoList", ToDo.todoList);
dispatcher.forward(request, response);
%>
<!-- (1) 끝 -->
<html>
<head>
<meta http-equiv="Content-Language" content="ko"/>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
<title>TODO 등록</title>
<style>
#todoList {
border: 1px solid #8F8F8F;
width: 500px;
border-collapse: collapse;
}
th, td {
padding: 5px;
border: 1px solid #8F8F8F;
}
</style>
<script>
function registerTodo(){
var todoName = document.getElementById("todoName").value;
var todoDate = document.getElementById("todoDate").value;
if(!todoName){
alert("할일을 입력해주세요..");
return false;
}
if(!todoDate){
alert("날짜를 입력해주세요.");
return false;
}
var form = document.getElementById("todoForm");
form.submit();
}
</script>
</head>
<body>
<h3>TO DO 등록</h3>
<div>
<form id="todoForm" method="POST" action="/todo_model1.jsp">
<input type="text" name="todoName" id="todoName" value=""/>
<input type="date" name="todoDate" id="todoDate" value=""/>
<input type="button" id="btnReg" value="등록" onclick="registerTodo()"/>
</form>
</div>
<div>
<h4>TO DO List</h4>
<table id="todoList">
<thead>
<tr>
<td align="center">todo name</td><td align="center">todo date</td>
</tr>
</thead>
<!-- (2) 시작 --->
<tbody>
<c:choose>
<c:when test="${fn:length(todoList) == 0}">
<tr>
<td align="center" colspan="2">할 일이 없습니다.</td>
</tr>
</c:when>
<c:otherwise>
<c:forEach items="${todoList}" var="todo">
<tr>
<td>${todo.todoName}</td><td align="center">${todo.todoDate}</td>
</tr>
</c:forEach>
</c:otherwise>
</c:choose>
</tbody>
<!-- (2) 끝 -->
</table>
</div>
</body>
</html>
위의 코드는 사용자가 자신의 할일을 등록하는 화면과 등록한 할일을 목록으로 보여주는 간단한 로직입니다.
- (1) : 클라이언트 요청을 처리하는 서버쪽 코드
- (2) : 서버로부터 전달 받은 응답을 화면에 표시하기 위한 JSP 에서 지원하는 jstl 태그 영역
- 나머지 : (1),(2) 영역 이외에 나머지 구현 코드
이렇게 가독성이 아주 떨어집니다.
여기서 만약 Java 코드를 분리해 서블릿 클래스로 분리할 수도 있습니다.
참고로 Spring 을 사용한 웹 요청을 처리할 때에도 내부적으로 Servlet 을 사용합니다.
이렇게 아주 긴 코드를 SpringMVC 에서 구현한다면 다음과 같을 수 있습니다.
@Controller
public class ToDoController {
@RequestMapping(value = "/todo", method = RequestMethod.POST)
@ResponseBody
public List<ToDo> todo(@RequestParam("todoName")String todoName,
@RequestParam("todoDate")String todoDate) {
ToDo.todoList.add(new ToDo(todoName, todoDate));
return ToDo.todoList;
}
@RequestMapping(value = "/todo", method = RequestMethod.GET)
@ResponseBody
public List<ToDo> todoList() {
return ToDo.todoList;
}
}
놀라올 정도로 간결해졌습니다.
그리고 이러한 SpringMVC 방식에서 데이터베이스 연결과 같은 복잡한 설정은
내부 속성 파일을 통해 아래의 코드와 같이 아주 간결하게 표현 가능합니다.
spring.h2.console.enabled=true
spring.h2.console.path=/console
spring.jpa.generate-ddl=true
spring.jpa.show-sql=true
이렇게 복잡한 설정 작업들을 Spring 이 대신 처리해주기 때문에
개발자는 애플리케이션 핵슴 비지니스 로직에만 집중할 수 있습니다.
스프링 부트 프로젝트 생성하기
1. https://start.spring.io/ 접속
2. 각종 디펜던씨 추가
3. 프로젝트 설정
4. 경로를 정해 GENERATE
* 이번에 진행할 환경
빌드 툴 - maven
언어 - java11
패키징 - jar
의존성 추가 - Spring Web
'스터디' 카테고리의 다른 글
웹 애플리케이션 구현 방식 (0) | 2022.08.03 |
---|---|
네트워크3 - URL,DNS (0) | 2022.08.02 |
네트워크2 - IP (0) | 2022.08.02 |
네트워크1 - 애플리케이션과 TCP/IP (0) | 2022.08.02 |
쇼핑몰 초기 프로젝트 구성 (0) | 2022.07.27 |