2019. 8. 2. 00:54ㆍSpringboot
sts3의 지원이 종료된 이 시점에서 서 개인프로젝트를 구상하는 중에 Springboot를 써볼까 하는 생각이 들었다.
okky에서도 자주 거론되는 주제인데 spring vs springBoot 에 대한 논쟁이 심심할때마다 올라온다.
위의 글은 스프링부트의 사용을 권장하는 블로그 글이다. 저 글을 보고 꽤 오래전에 springboot가 나왔다는 사실에 깜짝놀랐다.
네이버 책검색에 spring을 치면 관련서적이 수십개는 나오는 반면 springboot를 치면 고작 몇개밖에 없는것이 위의 글을 반영하는 현실인거 같다.
하지만 최근에 심심치 않게 구직사이트에 springboot기술을 요구하는 구인글들이 올라오고 okky에서 많은 개발자들이 springboot와 관련된 개발글들을 올리는 것을 보고 개발패러다임이 spring에서 springboot로 바뀌는 전환기인것을 느낄 수 있었다.
스프링 부트의 장점은 개발에서 환경설정이 차지하는 비중이 높은편인데 스프링부트는 그 환경설정 하는 부분을 간결하게 할수있는 강력한 장점이 있다. 또한 spring application을 최대한 빨리 실행시킨다는 장점도 있다.
또한 톰캣(Tomcat)이나 제티(Jetty)를 기본 내장할 수 있으며 웹 프로젝트 띄우는 시간이 독립적인 톰캣으로 띄우는 시간보다 반은 단축된다. 또한 이렇게 서블릿 컨테이너가 내장될 수 있으므로 프로젝트를 .jar 파일 형태로 간단히 만들어 배포할 수 있다.
본인은 개발도구로 요즘 개발자들이 많이 쓰고 있다는 intellij를 사용할 계획이다.
https://okky.kr/article/590234
개발도구로 Intellij가 각광받고 있는데 본인은 학원에서 파이널프로젝트를 했을시에 eclipse의 속도에 진저리가 났었다..
sts3플러그인을 사용해서 느린점도 있었지만 프로젝트의 규모가 커질수록 서버를 재시작하는것만으로도 시간을 많이 잡아먹어 고구마를 100개먹는 기분이 들었다.
인텔리제이를 테스트해보면서 가장 마음에 들었던점은 자동 코드완성기능과 빠른 속도감이였다.
이클립스에서는 플러그인을 깔아야 js나 기타 언어의 코드완성기능을 사용할 수 있지만, 이마저도 이상한걸 추천해주거나 뜨지않을경우가 매우매우 많았다.
하지만 이 인텔리제이... 진짜 내 뇌를 독심술로 파고든거마냥 코드에따라서 거의 내가원하는것을 대부분 바로 추천해준다.
인텔리제이의 최대단점은... 유료인것이다. 학생버전이 아닌이상 500달러를 주고 소프트웨어를 구매해야하는데 백수인 우리는 그런 거금을 들일 자본도 없다....
본인은 학생인 동생의 찬스를 빌려 인텔리제이 1년체험을 할 수 있게됬다. 사용해보니 돈주고 구매할 가치가 매우 충분했다.
여러 블로그를 검색해봤는데 eclipse로 프로젝트를 만드는 글은 많이 포스팅되어있지만 intellij로 프로젝트를 만드는 글이 적었었다.
intellij로 springboot프로젝트를 만드는분게 조금이나마 도움이 되고싶고, 자신도 이번기회에 인텔리제이로 프로젝트를 하나 만들어 보는 겸 intellij를 이용한 springboot프로젝트 만들기 포스팅을 시작하겠다.
1. IntelliJ를 시작하여 Create New Project를 선택해 새로운 프로젝트를 연다.
New Project -> Spring Initializr 프로젝트를 선택하고 자바 SDK를 설정한 후 Next 버튼을 누른다.
※ 실행전, 반드시 jdk설치와 환경변수 설정을 해주자
2. 프로젝트 이름, 빌드할 때 maven과 gradle 중 어느 것을 사용할지, 자바 버전 등 프로젝트의 기본적인 사항을 물어본다. 프로젝트 정보를 입력하고 Next 버튼을 누른다.
본인은 maven project가 아닌 gradle project를 사용했다.
3. 프로젝트에서 필요한 종류의 의존성을 추가한다
스프링부트 프로젝트와 관련된 글을 검색을 많이하고 이글을 본 사람이라면 뭔가 이상한점을 느꼈을것이다.
그렇다. 2.1.6버전(?)부터 web과 관련된 의존성 설정 명칭이 변경되었다.
기존의 web과 Spring web starter와 같은 것이므로 spring web starter를 선택해주면 된다.
본인은 devtools도 함께 선택해주었다.
4. 프로젝트의 이름과 경로를 확인한 후 finish를 누르면 프로젝트가 생성된다.
프로젝트가 생성되면서 위와같은 그레이들기반 구조로 생성된것을 확인 할 수 있다.
plugins {
id 'org.springframework.boot' version '2.1.6.RELEASE'
id 'java'
}
apply plugin: 'io.spring.dependency-management'
group = 'com.board'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = '1.8'
configurations {
developmentOnly
runtimeClasspath {
extendsFrom developmentOnly
}
}
repositories {
mavenCentral()
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-web'
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation 'org.springframework.boot:spring-boot-starter-test'
}
또한 springboot버전이 2.1.6대로 오면서 gradle 플러그인 설정이 buildscript방식이 아닌 plugins방식으로 설정이 된것을 확인할 수 있다.
http://honeymon.io/tech/2019/06/17/spring-boot-2-start.html
src>java를 보게되면 springboot프로젝트에서 기본으로 만들어준 어플리케이션실행 자바파일이 있다.
intellij에서는 eclipse와 다르게 프로젝트를 run server시키는게 아닌 실행 자바파일을 run시켜야 어플리케이션이 실행된다.
메뉴바에 run>run DemoApplication을 실행시켜준다.
"C:\Program Files\Java\jdk1.8.0_201\bin\java.exe" -XX:TieredStopAtLevel=1 -noverify -Dspring.output.ansi.enabled=always -Dcom.sun.management.jmxremote -Dspring.jmx.enabled=true -Dspring.liveBeansView.mbeanDomain -Dspring.application.admin.enabled=true "-javaagent:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\lib\idea_rt.jar=50631:C:\Program Files\JetBrains\IntelliJ IDEA 2019.2\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.8.0_201\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\cldrdata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\jfxrt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\nashorn.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\sunpkcs11.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jce.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jfxswt.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\resources.jar;C:\Program Files\Java\jdk1.8.0_201\jre\lib\rt.jar;E:\Intellj_Project\demo\build\classes\java\main;E:\Intellj_Project\demo\out\production\resources;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-web\2.1.6.RELEASE\8d232c9366b4ef3f5a919e48efb2228528391914\spring-boot-starter-web-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-json\2.1.6.RELEASE\ed82ba4ed8a45855f5571c0fbc15537aa942763\spring-boot-starter-json-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-devtools\2.1.6.RELEASE\1576e4c16cf810f8c40abf404ce3641a7d56eee3\spring-boot-devtools-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter\2.1.6.RELEASE\22f085f39ded75b0b454ee7731eccae68b20f17e\spring-boot-starter-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-tomcat\2.1.6.RELEASE\204079b2a82b794246fe911d29f1d9682efbd951\spring-boot-starter-tomcat-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.hibernate.validator\hibernate-validator\6.0.17.Final\af73055fc4a103ab347c56e7da5a143d68a0170\hibernate-validator-6.0.17.Final.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-webmvc\5.1.8.RELEASE\d2b6359b3b502ce917879990fbee99723bfa78c5\spring-webmvc-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-web\5.1.8.RELEASE\6d7134733f05133d82440172c5f6f9fe001db7ed\spring-web-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-autoconfigure\2.1.6.RELEASE\875d84cfa6d5655bd11238c229e7acedf344024b\spring-boot-autoconfigure-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot\2.1.6.RELEASE\b8a75ec9a9c570290523c4308c2255fbea6746c0\spring-boot-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework.boot\spring-boot-starter-logging\2.1.6.RELEASE\9cb7228f463fce085317e2da8fb824568e697b7c\spring-boot-starter-logging-2.1.6.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\javax.annotation\javax.annotation-api\1.3.2\934c04d3cfef185a8008e7bf34331b79730a9d43\javax.annotation-api-1.3.2.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-context\5.1.8.RELEASE\83ab599b042a4805bbee71b6241e9d073022d704\spring-context-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-aop\5.1.8.RELEASE\c013c5603a05bee2a80cc2ec8f3fc11b15d4de3a\spring-aop-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-beans\5.1.8.RELEASE\e35fa81d0142ef7c1247a7dee8b1ef2dd78c6322\spring-beans-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-expression\5.1.8.RELEASE\4f8340d8d4f52dbd527bd696358923ff4df5be1a\spring-expression-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-core\5.1.8.RELEASE\37fd45c92cfd05b9ad173ee1184ec4221e0f931f\spring-core-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jdk8\2.9.9\4b04126963103216c9c43b0f34bbc36315654204\jackson-datatype-jdk8-2.9.9.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.datatype\jackson-datatype-jsr310\2.9.9\a33df137557793b0404a486888dbe049f7abeeeb\jackson-datatype-jsr310-2.9.9.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.module\jackson-module-parameter-names\2.9.9\a92facb55a2538e7b2fe14294570a18b823ad431\jackson-module-parameter-names-2.9.9.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.yaml\snakeyaml\1.23\ec62d74fe50689c28c0ff5b35d3aebcaa8b5be68\snakeyaml-1.23.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-databind\2.9.9\d6eb9817d9c7289a91f043ac5ee02a6b3cc86238\jackson-databind-2.9.9.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-websocket\9.0.21\218f438e4812f268a1692511f897b401fc28cfa8\tomcat-embed-websocket-9.0.21.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-core\9.0.21\225a44fe65e9832f896e09f343ce107d38f3ee1b\tomcat-embed-core-9.0.21.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.apache.tomcat.embed\tomcat-embed-el\9.0.21\6a7ed3ad394b36d3f0f77745f424e19e976d2d61\tomcat-embed-el-9.0.21.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\javax.validation\validation-api\2.0.1.Final\cb855558e6271b1b32e716d24cb85c7f583ce09e\validation-api-2.0.1.Final.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.jboss.logging\jboss-logging\3.3.2.Final\3789d00e859632e6c6206adc0c71625559e6e3b0\jboss-logging-3.3.2.Final.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\com.fasterxml\classmate\1.4.0\291658ac2ce2476256c7115943652c0accb5c857\classmate-1.4.0.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-classic\1.2.3\7c4f3c474fb2c041d8028740440937705ebb473a\logback-classic-1.2.3.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-to-slf4j\2.11.2\6d37bf7b046c0ce2669f26b99365a2cfa45c4c18\log4j-to-slf4j-2.11.2.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.slf4j\jul-to-slf4j\1.7.26\8031352b2bb0a49e67818bf04c027aa92e645d5c\jul-to-slf4j-1.7.26.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.springframework\spring-jcl\5.1.8.RELEASE\60a3bb9c802ea03c955ee26526f8aebc9dd712b6\spring-jcl-5.1.8.RELEASE.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-annotations\2.9.0\7c10d545325e3a6e72e06381afe469fd40eb701\jackson-annotations-2.9.0.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\com.fasterxml.jackson.core\jackson-core\2.9.9\bfff5af9fb8347d26bbb7959cb9b4fe9a2b0ca5e\jackson-core-2.9.9.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\ch.qos.logback\logback-core\1.2.3\864344400c3d4d92dfeb0a305dc87d953677c03c\logback-core-1.2.3.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.slf4j\slf4j-api\1.7.26\77100a62c2e6f04b53977b9f541044d7d722693d\slf4j-api-1.7.26.jar;C:\Users\leejihye\.gradle\caches\modules-2\files-2.1\org.apache.logging.log4j\log4j-api\2.11.2\f5e9a2ffca496057d6891a3de65128efc636e26e\log4j-api-2.11.2.jar" com.board.demo.DemoApplication
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v2.1.6.RELEASE)
2019-08-02 00:34:06.516 INFO 1616 --- [ restartedMain] com.board.demo.DemoApplication : Starting DemoApplication on DESKTOP-56Q43O4 with PID 1616 (E:\Intellj_Project\demo\build\classes\java\main started by leejihye in E:\Intellj_Project\demo)
2019-08-02 00:34:06.524 INFO 1616 --- [ restartedMain] com.board.demo.DemoApplication : No active profile set, falling back to default profiles: default
2019-08-02 00:34:06.611 INFO 1616 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : Devtools property defaults active! Set 'spring.devtools.add-properties' to 'false' to disable
2019-08-02 00:34:06.612 INFO 1616 --- [ restartedMain] .e.DevToolsPropertyDefaultsPostProcessor : For additional web related logging consider setting the 'logging.level.web' property to 'DEBUG'
2019-08-02 00:34:08.415 INFO 1616 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8080 (http)
2019-08-02 00:34:08.462 INFO 1616 --- [ restartedMain] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2019-08-02 00:34:08.462 INFO 1616 --- [ restartedMain] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.21]
2019-08-02 00:34:08.572 INFO 1616 --- [ restartedMain] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2019-08-02 00:34:08.573 INFO 1616 --- [ restartedMain] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1961 ms
2019-08-02 00:34:08.854 INFO 1616 --- [ restartedMain] o.s.s.concurrent.ThreadPoolTaskExecutor : Initializing ExecutorService 'applicationTaskExecutor'
2019-08-02 00:34:09.000 INFO 1616 --- [ restartedMain] o.s.b.d.a.OptionalLiveReloadServer : LiveReload server is running on port 35729
2019-08-02 00:34:09.051 INFO 1616 --- [ restartedMain] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat started on port(s): 8080 (http) with context path ''
2019-08-02 00:34:09.054 INFO 1616 --- [ restartedMain] com.board.demo.DemoApplication : Started DemoApplication in 3.142 seconds (JVM running for 5.461)
콘솔창에 위와 같은 로그들이 찍히는데 로그를 살펴보자면 tomcat이 8080포트로 실행이 되었고 context path는 지정되지 않았다.
localhost:8080으로 접속을 해본다.
이건뭔가...에러페이지인가 하는생각이 들것이다. 하지만 정상적인 결과이다. 스프링부트로 프로젝트를 생성시 우리가 화면에 보이는 뷰페이지부분을 만들지 않았기 때문에 나는 에러이다.
뷰페이지를 보여주기위해 controller를 작성한다. 본인은 java파일을 따로 생성해 설정해줬다.
package com.board.demo;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class HelloController {
@RequestMapping("/")
public String hello(){
return "HelloWorld";
}
}
설정 후, DemoApplication을 다시한번 run 한다.
8080 접속시 helloworld가 잘 뜨는 것을 확인할 수 있다.
이렇게해서 기본적인 스프링부트 프로젝트 생성이 끝났다.
다음번엔 본격적으로 springboot를 이용한 게시판을 만들어볼 것이다.