CH5 스프링과 스프링 부트
5.1 스프링 웹 애플리케이션
5.1.1 J2EE 웹 애플리케이션
5.1.2 스프링 MVC 애플리케이션
5.1.3 스프링 부트 웹 애플리케이션
5.2 스프링 부트에서 스프링을!
5.2.1 XML 구성 가져오기
5.3 스프링 부트에서 스프링 기술 활용
- 5.1 : 웹 애플리케이션을 개발하는 전통 스프링 MVC 방식과 새로운 스프링 부트 방식의 차이점
- 5.2 : XML 파일 또는 자바 구성 애너테이션으로 기존 스프링 앱을 스프링 부트에서 사용하는 방법
- 5.3 : 모든 스프링 기술은 @Enable<기술명> 애너테이션만 있으면 간단히 불러 쓸 수 있다.
기존 스프링 앱 개발 방식과 스프링 부트의 새로운 개발 방식을 서로 비교하고 레거시 코드를 스프링 부트 앱으로 전환하는 문제를 다뤄보자.
![](https://t1.daumcdn.net/keditor/emoticon/niniz/large/012.gif)
5.1 스프링 웹 애플리케이션
5.1.1 J2EE 웹 애플리케이션
옛날 방식으로, 서블릿 2.4 명세와 메이븐 아키타입을 응용해서 J2EE 웹 애플리케이션을 작성해보자.
서블릿은 서버측에 HTML을 요청하는 첫 관문이다.
① 메이븐 실행 파일의 경로를 PATH에 추가하고 다음 명령으로 웹 프로젝트 템플릿을 생성한다.
$ mvn archetype:generate -DgroupId=com.apress.j2ee -DartifactId=simple-web-app -DarchetypeArtifactId=maven-archetype-webapp
실행이 끝나면 다음과같은 simple-web-app 폴더 구조가 만들어진다.
② 폼(pom.xml) 파일에 빠진 부분을 채워 넣는다.
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>2.4</version>
<scope>provided</scope>
</dependency>
서블릿 클래스를 작성할 때 꼭 필요한 servlet-api를 <dependencies></dependencies> 태그 안에 넣어준다.
<packaging>war</packaging>
이 프로젝트를 WAR(웹 아카이브) 파일로 배포할 거란 사실을 메이븐에 알리는 <packaging> 태그도 추가한다.
③ 서블릿 - SimpleServlet 클래스
package com.apress.j2ee;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class SimpleServlet extends HttpServlet {
protected void service(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
PrintWriter out = response.getWriter();
out.println("<html>");
out.println("<body>");
out.pintln("<h1>간단한 자바 웹 애플리케이션</h1>");
out.println("</body>");
out.println("</html>");
}
}
- SimpleServlet 클래스는 HttpServlet 을 상속한다.
- service 메서드는 PrintWriter 클래스(java.io.PrintWriter)로 응답 메시지를 준비한다.
- 어떤 URL 패턴을 이 서블릿 클래스로 보낼지는 WEB-INF 폴더에 위치한 web.xml 파일에 적는다. 즉, src/webapp/WEB-INF/web.xml 파일을 열어 서블릿을 선언해야 한다.
④ src/webapp/WEB-INF/web.xml 파일
<!DOCTYPE web-app PUBLIC
"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
<display-name>Archetype Created Web Application</display-name>
<servlet>
<servlet-name>SimpleServlet</servlet-name>
<display-name>SimpleServlet</display-name>
<description>간단한 서블릿</description>
<servlet-class>com.apress.j2ee.SimpleServlet</servlet-class>
</servlet>
<servlet-mapping>
<servlet-name>SimpleServlet</servlet-name>
<url-pattern>/SimpleServlet</url-pattern>
</servlet-mapping>
</web-app>
- <servlet> 태그에서 서블릿명을 선언 - ③에서 서블릿 이름이 SimpleServlet이니까 이걸 넣어주면 됨
- <servlet-mapping> 태그에서 요청끝점에 해당하는 URL로 서블릿을 매핑
⑤ 웹 애플리케이션 패키징
$ mvn clean package
- target/ 폴더에 simple-web-app.war 파일이 생성된다.
- WAR 파일을 <톰캣 설치 경로>/webapps/에 올려놓고, <톰캣 설치 경로>/bin에 있는 startup.sh 스크립트를 실행하여 서버를 실행해보자.
- 그 다음 웹 브라우저를 열고 http://localhost:8080/simple-web-app/SimpleServlet 에 접속하면 서블릿에 service 메서드 안에 내용이 화면에 텍스트로 출력된다.
출력 결과
- 간단한 자바 웹 애플리케이션
서블릿 탄생 이후 JSP(자바 서버 페이지)가 고안됐고, 그 이후로도 J2EE는 더욱 진화했다.
서블릿 3 명세부터는 web.xml 없이 @WebServlet 애너테이션을 붙여서 웹 애플리케이션을 개발할 수 있게 발전했다.
5.1.2 스프링 MVC 애플리케이션
스프링 프레임워크는 설정 및 사용이 간편한 MVC(모델-뷰-컨트롤러) 패턴을 도입함으로써 웹 애플리케이션 개발을 더욱 발전시켰다.
스프링 MVC 앱에 대해 설명하기 위해 5.1.1에서의 메이븐 아키타입을 그대로 사용해보자.
① 메이븐 실행 파일의 경로를 PATH에 추가하고 다음 명령으로 웹 프로젝트 템플릿을 생성한다.
$ mvn archetype:generate -DgroupId=com.apress.j2ee -DartifactId=simple-web-app -DarchetypeArtifactId=maven-archetype-webapp
위의 코드로 생성된 프로젝트는 옛날 버전이기 때문에 약간의 수정이 필요하다.
② 폼(pom.xml) 파일을 수정하자.
<properties>
<!-- 일반 프로퍼티 -->
<java.version>1.8</java.version>
<!-- 웹 -->
<jsp.version>2.2</jsp.version>
<jstl.version>1.2</jstl.version>
<servlet.version>2.5</servlet.version>
<!-- 스프링 -->
<spring-framework.version>3.2.3.RELEASE</spring-framework.version>
</properties>
<dependencies>
<!-- 스프링 MVC -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-framework</artifactId>
<version>${spring-framwork.version}</version>
</dependency>
<!-- 기타 웹 의존체 -->
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>jstl</artifactId>
<version>${jstl.version}</version>
</dependency>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>javax.servlet.jsp</groupId>
<artifactId>jsp-api</artifactId>
<version>${jsp.version}</version>
<scope>provided</scope>
</dependency>
</dependencies>
<build>
<finalName>simple-web-spring-app</finalName>
</build>
- 스프링 MVC 3.2.3.RELEASE 버전과 그 라이브러리 등 관련 의존체(jstl, jsp-api 등)가 포함됐다.
③ src/main/webapp/WEB-INF/web.xml 파일
서블릿 2.5 명세를 사용하려면 web.xml 버전을 2.3에서 2.5로 바꿔야 한다. J2EE에서 아주 성가신 일 중 하나이다.
<?xml version="1.0" encoding="ISO-8859-1"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http:java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd"
id="WebApp_ID" version="2.5">
<display-name>simple-web-spring-app</display-name>
<servlet>
<servlet-name>dispatcherServlet</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>/WEB-INF/mvc-config.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
</servlet>
<servlet-mapping>
<servlet-name>dispatcherServlet</servlet-name>
<url-pattern>/</url-pattern>
</servlet-mapping>
</web-app>
- 버전이 2.5 (서블릿 엔진 버전)로 변경됐다.
- org.springframework.web.servlet.DispatcherServlet 클래스를 메인 디스패처로 추가해서 MVC 패턴을 걸었다.
- <init-param> 태그에서 contextConfigLocation 파라미터 값으로 지정한 WEB-INF/mvc-config.xml은 스프링이 찾는 XML 구성 파일로, 스프링 컨텍스트를 구성하는 파일이기도 하다.
④ src/main/webapp/WEB-INF/mvc-config.xml 파일
컨테이너에 초기화할 스프링 빈을 정의하는 전형적인 스프링 구성 파일
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="htttp://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<bean name="/showMessage.html" class="com.apress.spring.SimpleController" />
<bean class="org.springframework.web.servlet.view.InternalResourceViesResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
- 이름이 /showMessage.html인 빈을 com.apress.spring.SimpleController라는 자바 클래스와 엮었다. - 클라이언트가 /showMessage.html URL로 요청하면 이 클래스를 실행하라는 의미이다.
- InternalResourceViewResolver 클래스로 뷰 리졸버를 선언했다. - 여기선 모든 뷰 파일이 /WEB-INF/view에 있고 각 페이지엔 .jsp 확장자를 붙인다는 의미이다.
⑤ 컨트롤러 - com.apress.spring.SimpleController 클래스
요청(/showMessage.html)을 처리하는 로직이 모두 담긴 추상 클래스 AbstractController를 확장한 클래스이다.
package com.apress.spring;
import javax.servlet.http.httpServletRequest;
import javax.servlet.http.httpServletResponse;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.AbstractController;
public class SimpleController extends AbstractController {
@Override
protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response) throws Exception {
ModelAndView model = new ModelAndView("showMessage");
model.addObject("message", "스프링 MVC 웹 애플리케이션");
return model;
}
}
- handleRequestInternal 메서드를 재정의(@Override)해서 화면에 표시할 뷰 정보가 담긴 ModelAndView 인스턴스를 반환하는 것으로 클라이언트에 응답한다. 이 인스턴스는 message 변수에 '스프링 MVC 웹 애플리케이션'이라는 문자열을 실어 나른다.
- ModelAndView model = new ModelAndView("showMessage"); 선언을 통해 스프링 MVC는 실제로 렌더링할 뷰가 showMessage라고 인식한다. 이 뷰가 바로 /WEB-INF/view/showMessage.jsp 파일이고, 페이지로 보여주는 일은 mvc-config.xml 파일에 있는 InternalResourceViewResolver 클래스가 수행한다.
⑥ 뷰 - src/main/webapp/WEB-INF/view/showMessage.jsp
<!DOCTYPE html>
<%@ page language="java" contentType="text/html; charset=UTF-8" pageEncoding="UTF-8" %>
<html>
<head>
<meta charset="utf-8">
<title>환영합니다</title>
</head>
<body>
<h2>${message}</h2>
</body>
</html>
- <h2>태그 안에 있는 ${message}값은 컨트롤러에서 model 인스턴스에 담아둔 message 변수의 값을 가져온다. 즉, ${message}값이 "스프링 MVC 애플리케이션"이란 문자열로 바뀐다.
⑦ 앱 패키징 후 서버에 배포
$ mvn clean package
- 앱을 패키징하면 target/simple-web-spring-app.war 파일이 생성된다.
- 이 파일을 서버에 배포한 후, http://localhost:8080/simple-web-spring-app/showMessage.html에 접속해보자.
- 화면에 "스프링 MVC 애플리케이션"이 보이면 성공적으로 수행된 것이다.
간단한 스프링 MVC 애플리케이션 완성!
![](https://t1.daumcdn.net/keditor/emoticon/niniz/large/043.gif)
스프링 MVC 2.5, 3, 4 버전부터는 다른 클래스를 상속하거나 한 클래스에 여러 가지를 매핑하지 않아도 애너테이션만 붙여 개발이 가능하다.
⑧ 애너테이션을 사용한 컨트롤러 - com.apress.spring.SimpleController 클래스
package com.apress.spring;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.servlet.ModelAndView;
@Controller
@RequestMapping("/showMessage.html")
public class SimpleController {
@RequestMapping(method=RequestMethod.GET)
public ModelAndView helloWorld() {
ModelAndView model = new ModelAndView("showMessage");
model.addObject("message", "애너테이션을 사용한 스프링 MVC 웹 애플리케이션");
return model;
}
}
⑨ src/main/webapp/WEB-INF/mvc-config.xml 파일
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="htttp://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-pacakage="com.apress.spring" />
<bean class="org.springframework.web.servlet.view.InternalResourceViesResolver">
<property name="prefix" value="/WEB-INF/view/" />
<property name="suffix" value=".jsp" />
</bean>
</beans>
- <context:component-scan> 태그는 스프링으로 하여금 com..apress.spring 패키지 레벨에서 애너테이션으로 표시한 클래스를 찾게한다.
![](https://t1.daumcdn.net/keditor/emoticon/niniz/large/005.gif)
5.1.3 스프링 부트 웹 애플리케이션
① simple-web-spring-boot 폴더 생성 후 스프링 부트 웹 프로젝트 생성
$ mkdir simple-web-spring-boot
$ cd simple-web-spring-boot
$ spring init -d=web -g=com.apress.spring -a=simple-web-spring-boot --pacakage-name=com.apress.spring -name=simple-web-spring-boot -x
- -d=web : 웹 관련 의존체(spring-boot-starter-web) 포함
- -g : 그룹 이름
- -a : 아티팩트 ID
- --package-name : 패키지명
- -name : 애플리케이션명
- -x : 현재 폴더에 템플릿 압축 파일 풀기
② 메인 클래스 - com.apress.spring.SimpleWebSpringBootApplication 클래스
package com.apress.spring;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.bind.annotation.RequestMapping;
@RestController
@SpringBootApplication
public class SimpleWebSpringBootApplication {
@RequestMapping("/showMessage.html")
public String index() {
return "스프링 부트 시작!";
}
public static void main(String[] args){
SpringApplication.run(SimpleWebSpringBootApplication.class, args);
}
}
- @RestController 애너테이션을 붙여 웹 REST 컨트롤러임을 알린다.
- @RequestMapping 애너테이션을 붙여 /showMessage.html 요청을 index 메서드가 처리하게 한다.
- @SpringBootApplication 애너테이션은 SpringApplication.run으로 실행하는 main 메서드와 클래스패스를 기반으로 앱을 자동 구성한다.
③ 실행
앱이 시동하면 내장 톰캣 서버도 함께 실행되고 8080 포트를 리스닝한다.
$ ./mvnw spring-boot:run
위의 명령으로 앱을 실행하고 브라우저 주소 창에 http://localhost:8080/showMessage.html을 입력하자.
화면에 "스프링 부트 시작!" 이라고 보이면 성공적으로 수행된 것이다.
결론
5.1.1에서는 옛 자바로, 5.1.2에서는 스프링 MVC로, 5.1.3에서는 스프링 부트로 웹 애플리케이션을 만들어보았다. 이 과정에서 셋을 비교해보자면, 스프링 MVC는 여전히 스프링 부트 웹 애플리케이션의 기본 틀이지만, 스프링 부트는 개발 과정이 훨씬 간편하고 구성 파일을 없앴다는 것이 기존 자바/ 스프링 MVC와 구별되는 점이다. 즉, 스프링 부트는 XML 파일을 상대할 필요가 없는 것이다.
5.2 스프링 부트에서 스프링을!
스프링 컨테이너와 구성을 살펴보고 스프링 부트에 통합하는 과정을 알아보자.
![](https://t1.daumcdn.net/keditor/emoticon/niniz/large/040.gif)
스프링
초기 스프링 프레임워크는 XML 구성 파일에 지나치게 의존했다. 자바 5 출시 이후 자바 클래스(애너테이션)로도 구성할 수 있게 되면서 @Configuration 및 @Bean으로 스프링 컨테이너를 구성하게 되었다.
스프링 부트
스프링 부트도 마찬가지로 XML 파일이건 애너테이션이건 어느 쪽이든 가능하다.
5.2.1 XML 구성 가져오기
XML 구성 파일이 여럿 있으면 메인 애플리케이션에서 애너테이션 하나로 합칠 수 있다. 각 XML 구성 파일의 경로와 이름을 org.springframework.context.annotation.ImportResource 애너테이션에 String 배열 형태로 넘기면 된다.
스프링 부트 앱에서는 기존 메인 스프링 부트 앱의 XML 구성 파일(또는 자바 구성 클래스)을 아래와 같이 쓰면 된다.
@ImportResource({"META-INF/spring/services-context.xml", "META-INF/spring/repositories-context.xml"})
@SpringBootApplication
public class SpringXMLApplication {
...
}
혹은 기존 자바 구성 클래스에서 XML 구성 파일을 재사용할 수도 있다.
@ImportResource("classpath:applicationContext.xml")
@Configuration
public class SimpleConfiguration [
...
}
혹은 main 메서드에서 XML 파일을 불러올 수도 있다.
public class Application {
public static void main(String[] args) throws Exception {
ConfigurableApplicationContext ctx = new SpringApplication("/META-INF/spring/integration.xml").run(args);
...
}
}
5.3 스프링 부트에서 스프링 기술 활용
스프링 부트는 결국 스프링이고 XML 파일이나 자바 구성 클래스에서 선언한 빈을 자유롭게 사용할 수 있다.
따라서 스프링 프레임워크 4 버전부터 새로 등장한 애너테이션을 이용한 자동 구성을 통해 스프링 JMS, 스프링 AMQP, 스프링 통합, 스프링 캐싱, 스프링 세션, 스프링 REST 등 다른 스프링 기술을 스프링 부트에서 불러 쓸 수 있다.
위의 각 기술마다 @Enable<기술명> 애너테이션을 하나씩 갖고 있다.
애너테이션 | 설명 |
@EnalbeJms | JMS 메시징 |
@EnableCaching | 캐시 추상화 |
@EnableRabbit | 래빗MQ로 AMQP 메시징 |
@EnableBatchProcessing | 스프링 배치 |
@EnableWebSecurity | 스프링 시큐리티 |
@EnableRedisHttpSession | 스프링 세션 |
@EnableJpaRepositories | 스프링 데이터 |
@EnableIntegration | 스프링 통합 |
![](https://t1.daumcdn.net/keditor/emoticon/niniz/large/010.gif)
'BOOK REVIEW > 실전 스프링 부트 워크북' 카테고리의 다른 글
[실전 스프링 부트 워크북] CH12 스프링 부트 배포 - SSL 기능 통합하여 배포하기 (0) | 2021.08.19 |
---|---|
[실전 스프링 부트 워크북] CH6. 스프링 부트 테스트 (0) | 2021.08.16 |
[실전 스프링 부트 워크북] 스프링부트 애플리케이션 구성 알아보기 / 스프링 부트 프로젝트 따라하기 (0) | 2021.08.14 |
[실전 스프링 부트 워크북] CH3 스프링 부트 자동 구성과 주요 기능 (0) | 2021.08.13 |
[실전 스프링 부트 워크북] 스프링 부트 일기 / 스프링 부트 프로젝트 따라하기 (0) | 2021.08.10 |