Spring Bootアプリを新規に作る場合、多くの方は以下のいずれかの方法で開発プロジェクトを作成していると思います。
- SPRING INITIALIZRのWeb UI
- IDE(STSやIntelliJ IDEAなど)に組み込まれているSPRING INITIALIZRのプロジェクト作成ウィザード
Web UIやIDEのウィザードを使うと指定可能な依存アーティファクトの検索を行うことができ、入力フォームに値を指定してポチポチするだけで開発プロジェクトが簡単に作成できちゃいます。これは非常に便利で私も愛用していますが、UI操作自体が面倒だな〜と思う時もあります。
そんな時はCLIですよね〜
Spring Bootは、Spring Boot提供のコマンドを使って開発プロジェクトを作成する方法もサポートしていますが、今回はcurl
とtar
コマンドを使う方法を紹介します。
スタンドアロンアプリ用のプロジェクトを作る
以下のようなコマンドを実行すると、スタンドアロンアプリ(=非WEB)向けの開発プロジェクトがつくれます。
$ curl -s https://start.spring.io/starter.tgz -d baseDir=demo | tar -xzvf -
x demo/mvnw
x demo/
x demo/.mvn/
x demo/.mvn/wrapper/
x demo/src/
x demo/src/main/
x demo/src/main/java/
x demo/src/main/java/com/
x demo/src/main/java/com/example/
x demo/src/main/resources/
x demo/src/test/
x demo/src/test/java/
x demo/src/test/java/com/
x demo/src/test/java/com/example/
x demo/.gitignore
x demo/.mvn/wrapper/maven-wrapper.jar
x demo/.mvn/wrapper/maven-wrapper.properties
x demo/mvnw.cmd
x demo/pom.xml
x demo/src/main/java/com/example/DemoApplication.java
x demo/src/main/resources/application.properties
x demo/src/test/java/com/example/DemoApplicationTests.java
$ tree demo
demo
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── DemoApplication.java
│ └── resources
│ └── application.properties
└── test
└── java
└── com
└── example
└── DemoApplicationTests.java
ビルドしてみる。
$ cd demo
$ ./mvnw clean package
実行してみる。
$ java -jar target/demo-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.3.RELEASE)
2017-01-03 15:38:28.749 INFO 31974 --- [ main] com.example.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT on Kazuki-no-MacBook-Pro.local with PID 31974 (/usr/local/apps/demo/target/demo-0.0.1-SNAPSHOT.jar started by shimizukazuki in /usr/local/apps/demo)
2017-01-03 15:38:28.751 INFO 31974 --- [ main] com.example.DemoApplication : No active profile set, falling back to default profiles: default
2017-01-03 15:38:28.794 INFO 31974 --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@5b37e0d2: startup date [Tue Jan 03 15:38:28 JST 2017]; root of context hierarchy
2017-01-03 15:38:29.312 INFO 31974 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-01-03 15:38:29.323 INFO 31974 --- [ main] com.example.DemoApplication : Started DemoApplication in 0.843 seconds (JVM running for 1.151)
2017-01-03 15:38:29.324 INFO 31974 --- [ Thread-1] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@5b37e0d2: startup date [Tue Jan 03 15:38:28 JST 2017]; root of context hierarchy
2017-01-03 15:38:29.325 INFO 31974 --- [ Thread-1] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
WEBアプリ用のプロジェクトを作る
以下のようなコマンド(dependenciesにwebを指定)を実行すると、WEBアプリ向けの開発プロジェクトがつくれます。
$ curl -s https://start.spring.io/starter.tgz -d name=web-demo -d artifactId=web-demo -d dependencies=web -d baseDir=web-demo | tar -xzvf -
x web-demo/mvnw
x web-demo/
x web-demo/.mvn/
x web-demo/.mvn/wrapper/
x web-demo/src/
x web-demo/src/main/
x web-demo/src/main/java/
x web-demo/src/main/java/com/
x web-demo/src/main/java/com/example/
x web-demo/src/main/resources/
x web-demo/src/main/resources/static/
x web-demo/src/main/resources/templates/
x web-demo/src/test/
x web-demo/src/test/java/
x web-demo/src/test/java/com/
x web-demo/src/test/java/com/example/
x web-demo/.gitignore
x web-demo/.mvn/wrapper/maven-wrapper.jar
x web-demo/.mvn/wrapper/maven-wrapper.properties
x web-demo/mvnw.cmd
x web-demo/pom.xml
x web-demo/src/main/java/com/example/WebDemoApplication.java
x web-demo/src/main/resources/application.properties
x web-demo/src/test/java/com/example/WebDemoApplicationTests.java
$ tree web-demo
web-demo
├── mvnw
├── mvnw.cmd
├── pom.xml
└── src
├── main
│ ├── java
│ │ └── com
│ │ └── example
│ │ └── WebDemoApplication.java
│ └── resources
│ ├── application.properties
│ ├── static
│ └── templates
└── test
└── java
└── com
└── example
└── WebDemoApplicationTests.java
ビルドしてみる。
$ cd web-demo
$ ./mvnw clean package
実行してみる。
$ java -jar target/web-demo-0.0.1-SNAPSHOT.jar
. ____ _ __ _ _
/\\ / ___'_ __ _ _(_)_ __ __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
\\/ ___)| |_)| | | | | || (_| | ) ) ) )
' |____| .__|_| |_|_| |_\__, | / / / /
=========|_|==============|___/=/_/_/_/
:: Spring Boot :: (v1.4.3.RELEASE)
2017-01-03 15:48:49.606 INFO 32190 --- [ main] com.example.WebDemoApplication : Starting WebDemoApplication v0.0.1-SNAPSHOT on Kazuki-no-MacBook-Pro.local with PID 32190 (/usr/local/apps/web-demo/target/web-demo-0.0.1-SNAPSHOT.jar started by shimizukazuki in /usr/local/apps/web-demo)
2017-01-03 15:48:49.608 INFO 32190 --- [ main] com.example.WebDemoApplication : No active profile set, falling back to default profiles: default
2017-01-03 15:48:49.658 INFO 32190 --- [ main] ationConfigEmbeddedWebApplicationContext : Refreshing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4bf558aa: startup date [Tue Jan 03 15:48:49 JST 2017]; root of context hierarchy
2017-01-03 15:48:50.658 INFO 32190 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat initialized with port(s): 8080 (http)
2017-01-03 15:48:50.670 INFO 32190 --- [ main] o.apache.catalina.core.StandardService : Starting service Tomcat
2017-01-03 15:48:50.671 INFO 32190 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet Engine: Apache Tomcat/8.5.6
2017-01-03 15:48:50.744 INFO 32190 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2017-01-03 15:48:50.744 INFO 32190 --- [ost-startStop-1] o.s.web.context.ContextLoader : Root WebApplicationContext: initialization completed in 1089 ms
2017-01-03 15:48:50.855 INFO 32190 --- [ost-startStop-1] o.s.b.w.servlet.ServletRegistrationBean : Mapping servlet: 'dispatcherServlet' to [/]
2017-01-03 15:48:50.858 INFO 32190 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'characterEncodingFilter' to: [/*]
2017-01-03 15:48:50.858 INFO 32190 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]
2017-01-03 15:48:50.858 INFO 32190 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'httpPutFormContentFilter' to: [/*]
2017-01-03 15:48:50.858 INFO 32190 --- [ost-startStop-1] o.s.b.w.servlet.FilterRegistrationBean : Mapping filter: 'requestContextFilter' to: [/*]
2017-01-03 15:48:51.071 INFO 32190 --- [ main] s.w.s.m.m.a.RequestMappingHandlerAdapter : Looking for @ControllerAdvice: org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@4bf558aa: startup date [Tue Jan 03 15:48:49 JST 2017]; root of context hierarchy
2017-01-03 15:48:51.123 INFO 32190 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error]}" onto public org.springframework.http.ResponseEntity<java.util.Map<java.lang.String, java.lang.Object>> org.springframework.boot.autoconfigure.web.BasicErrorController.error(javax.servlet.http.HttpServletRequest)
2017-01-03 15:48:51.124 INFO 32190 --- [ main] s.w.s.m.m.a.RequestMappingHandlerMapping : Mapped "{[/error],produces=[text/html]}" onto public org.springframework.web.servlet.ModelAndView org.springframework.boot.autoconfigure.web.BasicErrorController.errorHtml(javax.servlet.http.HttpServletRequest,javax.servlet.http.HttpServletResponse)
2017-01-03 15:48:51.147 INFO 32190 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/webjars/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-01-03 15:48:51.147 INFO 32190 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-01-03 15:48:51.173 INFO 32190 --- [ main] o.s.w.s.handler.SimpleUrlHandlerMapping : Mapped URL path [/**/favicon.ico] onto handler of type [class org.springframework.web.servlet.resource.ResourceHttpRequestHandler]
2017-01-03 15:48:51.282 INFO 32190 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans for JMX exposure on startup
2017-01-03 15:48:51.335 INFO 32190 --- [ main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
2017-01-03 15:48:51.338 INFO 32190 --- [ main] com.example.WebDemoApplication : Started WebDemoApplication in 2.123 seconds (JVM running for 2.45)
起動したTomcatにアクセスしてみる。
$ curl http://localhost:8080/
{"timestamp":1483426201099,"status":404,"error":"Not Found","message":"No message available","path":"/"}
エンドポイントを作っていないので、404 Not Foundエラーになるのは正しい動作ですね。
詳しくは・・・
Spring InitializrのGitHubのREADMEを読みましょう。
まとめ
作るものが予め決まっている場合(例えば、開発環境をセットアップする際の手順などの場合)は・・・GUIを使うのではなく、CLIを使ってワンライナーで(=コマンドをコピって)開発プロジェクト作る手順にしておくと効率的ですよね。