Spring Boot 란?
- Spring 프로젝트가 제공하는 다양한 라이브러리와 프레임워크로 빨리게 사용할 수 있게 하는 프레임워크.
- Dropwizard의 Spring 버전 같은 것.
- 빌드하면 단일 jar 파일이 생긴다.
- Web 어플리케이션의 경우, 내장 Tomcat을 시작 (Jetty와 Undertow로 전환 가능).
- Web 응용 프로그램이 아니라 보통의 Java 프로그램으로도 동작하게 할 수 있다.
- Maven이나 Gradle 같은 빌드 도구를 사용한다(Ant로는 가능하지 않다)
- 사용하려는 컨포넌트를 종속적으로 추가하면 결합에 필요한 설정이 자동으로 이루어진다.
Hello World
Hello World 생성하기
Gradle 프로젝트를 생성한다.
디렉토리 spring-boot-hello-world를 생성하고, Gradle 프로젝트를 초기화한다.
$ mkdir spring-boot-hello-world
$ cd spring-boot-hello-world
Gradle 프로젝트를 초기화한다.
$ gradle init
BUILD SUCCESSFUL in 1s
2 actionable tasks: 2 executed
소스 코드 자바 디렉토리를 만든다.
$ mkdir -p src/main/java/sample/springboot
소스 코드를 작성한다.
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.6.RELEASE")
}
}
apply plugin: 'java'
apply plugin: 'org.springframework.boot'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
mavenCentral()
}
dependencies {
compile("org.springframework.boot:spring-boot-starter-web")
}
jar.baseName = 'spring-boot-hello-world'
src/main/java/sample/springboot/Main.java
package sample.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Main m = ctx.getBean(Main.class);
m.hello();
}
}
public void hello() {
System.out.println("Hello Spring Boot!!");
}
}
디렉토리 구조
$ tree
.
├── build.gradle
├── gradle
│ └── wrapper
│ ├── gradle-wrapper.jar
│ └── gradle-wrapper.properties
├── gradlew
├── gradlew.bat
├── settings.gradle
└── src
└── main
└── java
└── sample
└── springboot
└── Main.java
어플리케이션 실행
Gradle로 실행
$ gradle bootRun
> Task :bootRun
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.6.RELEASE)
(생략)
Hello Spring Boot!!
(생략)
BUILD SUCCESSFUL in 20s
3 actionable tasks: 3 executed
빌드 실행
$ gradle build
$ java -jar build/libs/spring-boot-hello-world.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.5.6.RELEASE)
(생략)
Hello Spring Boot!!
(생략)
설명
build.gradle 설정
Spring Boot 용 Gradle 플러그인이 포함되어 있기 때문에 처음에 이를 로드한다.
build.gradle
buildscript {
repositories {
mavenCentral()
}
dependencies {
classpath("org.springframework.boot:spring-boot-gradle-plugin:1.5.6.RELEASE")
}
}
apply plugin: 'org.springframework.boot'
그리고 일반적인 Java 프로그램을 만들 뿐이라면, spring-boot-starter에 종속(dependencies)되도록 추가한다.
build.gradle
repositories {
mavenCentral()
}
dependencies {
compile 'org.springframework.boot:spring-boot-starter'
}
Spring Boot 기동
Spring Boot의 기동은 SpringApplication 클래스를 사용한다. 가장 간단한 방법은 SpringApplication#run (Object, String ...)을 사용하는 것이다.
Main.java
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Main m = ctx.getBean(Main.class);
m.hello();
}
}
public void hello() {
System.out.println("Hello Spring Boot!!");
}
}
- run () 메소드의 첫번째 인수는 @EnableAutoConfiguration으로 어노테이션 클래스의 Class 객체를 건네 준다.
- Main 클래스는 @SpringBootApplication 어노테이션되어 있지만, 이것은 @Configuration, @EnableAutoConfiguration, @ComponentScan 3개의 클래스를 어노테이션 설정한 것과 동일하다.
- @Configuration은 Spring의 다양한 설정을 Java 코드상에서 할 수 있도록 한 어노테이션이다.
- 예전 Spring은 XML으로 설정을 썼지만, 지금은 Java 코드에서 설정하는 것이 주류를 이루고 있다 같다.
- @EnableAutoConfiguration는 Spring 설정을 자동화하기 위한 어노테이션이다.
- 이 종속성을 추가하는 것만으로 Spring MVC 등의 라이브러리를 설정 기입없이 사용할 수있게 된다.
- @ComponentScan는 DI 컨테이너가 관리하는 Bean을 자동 등록하는 어노테이션이다.
- 이제 주석 된 클래스를 기점으로 부하의 패키지를 재귀적으로 검색하여 @Component 어노테이션이 부여 된 클래스를 Bean으로 컨테이너에 등록한다.
- 이 3 개의 어노테이션은 대체로 함께 사용하는 경우이 많기 때문에, @SpringBootApplication를 사용하면 조금 편해진다.
- 두 번째 인수는 커멘드 라인의 인수를 전달한다.
Gradle에서 실행 빌드
어플리케이션의 기동은 spring-boot-gradle-plugin이 제공하는 bootRun 테스크를 사용한다.
jar 생성은, 보통의 build 테스크로 가능하다.
생성된 jar는 일반적으로 jar -jar <jar 파일>
에서 실행할 수 있다.
소스 코드
Java 코드에서 Bean 정의
@Bean 어노테이션를 부여하여 Bean 생성하기
Hoge.java
package sample.springboot;
public class Hoge {
private String name;
public Hoge(String name) {
this.name = name;
}
@Override
public String toString() {
return "Hoge [name=" + name + "]";
}
}
Main.java
package sample.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Hoge h = ctx.getBean(Hoge.class);
System.out.println(h);
}
}
@Bean
public Hoge getHoge() {
System.out.println("Main#getHoge()");
return new Hoge("hoge");
}
}
실행 결과
Main#getHoge()
Hoge [name=hoge]
설명
- @Bean 메소드를 어노테이션으로 설정하고 그 메소드를 통해 Bean의 인스턴스를 생성 할 수있게 된다.
- 이런 방식의 Bean을 정의하는 방법은 @Configuration 어노테이션이 부여 된 클래스를 선언 할 수 있다.
- @SpringBootApplication는 @Configuration 어노테이션이 부여 된 것과 같은 효과가 있다.
@Configuration 어노테이션이 부여 된 클래스를 별도로 생성하기
HogeProvider.java
package sample.springboot;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class HogeProvider {
@Bean
public Hoge getHoge() {
System.out.println("HogeProvider#getHoge()");
return new Hoge("hoge provider");
}
}
Main.java
package sample.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
Hoge h = ctx.getBean(Hoge.class);
System.out.println(h);
}
}
}
실행 결과
HogeProvider#getHoge()
Hoge [name=hoge provider]
설명
클래스에 @Configuration 어노테이션으로 부여하고 메소드에 @Bean 어노테이션으로 부여하면, 임의의 클래스 Bean을 생성하는 메소드를 정의할 수 있다.
Web 어플리케이션 기동
Hello World 수정하기
build.gradle
dependencies {
- compile 'org.springframework.boot:spring-boot-starter'
+ compile 'org.springframework.boot:spring-boot-starter-web'
}
src/main/java/sample/springboot/Main.java
package sample.springboot;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class Main {
public static void main(String[] args) {
SpringApplication.run(Main.class, args);
}
}
src/main/java/sample/springboot/web/HelloController.java
package sample.springboot.web;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method=RequestMethod.GET)
public String hello() {
return "Hello Spring MVC";
}
}
어플리케이션 실행
Gradle로 실행
$ gradle bootRun
(생략)
> :bootRun
curl으로 테스트하기
$ curl http://localhost:8080/hello
Hello Spring MVC
설명
Web 어플리케이션에 대한 의존성
build.gradle
dependencies {
- compile 'org.springframework.boot:spring-boot-starter'
+ compile 'org.springframework.boot:spring-boot-starter-web'
}
Web 어플리케이션을 만드는 경우는 spring-boot-starter-web 모듈을 사용한다. 기본적으로 Spring MVC를 사용하여 Web 응용 프로그램을 만들게 된다.
기동 방법 변경
src/main/java/sample/springboot/Main.java
public static void main(String[] args) {
- try (ConfigurableApplicationContext ctx = SpringApplication.run(Main.class, args)) {
- ....
- }
+ SpringApplication.run(Main.class, args);
서버 시작 후 컨테이너가 종료 해 버리므로 try-with-resources 문장은 사용하지 않도록 변경한다.
Spring MVC 컨트롤러 클래스
src/main/java/sample/springboot/web/HelloController.java
@RestController
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method=RequestMethod.GET)
public String hello() {
return "Hello Spring MVC";
}
}
Web API의 진입 점(Entry point)이 되는 클래스를 만드는 경우 @RestController을 클래스에 부여한다.
Web API 대신 MVC에서 C가 되는 컨트롤러 원한다면 @Controller 어노테이션을 부여한다.
@RequestMapping에서 경로 및 HTTP 메소드의 매핑을 한다 (대략 JAX-RS와 같은 분위기).
소스 코드
서버 포트 번호 변경
서버 포트 번호 변경하기
application.properties
server.port=1598
어플리케이션 실행
$ gradle bootRun
(생략)
2017-08-17 22:30:13.211 INFO 14485 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 1598 (http)
(생략)
설명
- server.port으로 포트 번호를 지정할 수 있다.
- application.properties에 대한 설명은 여기.
- 그 밖에도 다음과 같은 변경이 가능하다.
- server.address : 서버 주소 (localhost로 하면 로컬에서만 액세스 할 수 없게 된다.)
- server.sessionTimeout : 세션 타임아웃 시간.
응답과 요청 매핑
응답과 요청 매핑(Mapping Requests and Responses)
src/main/java/sample/springboot/web/Hoge.java
package sample.springboot.web;
public class Hoge {
public int id;
public String value;
@Override
public String toString() {
return "Hoge [id=" + id + ", value=" + value + "]";
}
}
src/main/java/sample/springboot/web/HelloController.java
package sample.springboot.web;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
@RestController
@RequestMapping("/hello")
public class HelloController {
@RequestMapping(method=RequestMethod.POST)
public Hoge hello(@RequestBody Hoge param) {
System.out.println(param);
Hoge hoge = new Hoge();
hoge.id = 20;
hoge.value = "Response";
return hoge;
}
}
어플리케이션 실행
curl으로 테스트하기
$ curl -H "Content-type: application/json" -X POST -d '{"id": 10, "value": "Request"}' http://localhost:8080/hello
{"id":20,"value":"Response"}
서버 콘솔 출력
Hoge [id=10, value=Request]
설명
- 기본적으로 요청과 응답은 모두 JSON 의한 매핑이 되어 있다.
- 매핑은 Jackson으로 하고 있고 있다 (그래서 매핑 조정은 Jackson 어노테이션으로 가능하다).
'Spring Boot' 카테고리의 다른 글
[Spring Boot] Thymeleaf 엔진 사용 (0) | 2017.10.29 |
---|---|
[Spring Boot] WebJars 이용하기 (0) | 2017.10.29 |
[Spring Boot] 정적(static) 파일을 배치하기 (0) | 2017.10.29 |
[Spring Boot] 예외 처리 (0) | 2017.10.29 |
[Spring Boot] Spring MVC의 간단한 사용법 (2) | 2017.10.29 |
[Spring Boot] Spring Boot 이란? (0) | 2017.10.29 |