12つのプロジェクトの tree を並べる
左は で を作って に置く構成、右は の雛形です。左は に を手で置き、src の直下からが始まります。右は がプロジェクトの中に無く、 の下にパッケージがあります。
shop/ (Ant + WAR + 外部 Tomcat) boot-pristine/ (Maven + Spring Boot)├── build.xml ├── pom.xml├── lib/ ← JAR 11本を手で置く ├── mvnw, mvnw.cmd, .mvn/wrapper/├── lib-compile/ ← servlet-api ├── .gitignore, .gitattributes, HELP.md├── WebContent/ └── src/│ ├── index.html ├── main/│ └── WEB-INF/ │ ├── java/com/example/demo/│ ├── web.xml │ │ └── DemoApplication.java│ ├── applicationContext.xml │ └── resources/│ └── dispatcher-servlet.xml │ ├── application.properties└── src/ │ ├── static/└── jp/co/example/shop/ │ └── templates/├── service/GreetingService.java └── test/java/com/example/demo/└── web/HelloController.java └── DemoApplicationTests.java(11 directories, 19 files) (16 directories, 10 files)
2見分けの手がかりの一覧
ルートのビルド定義から順に、2つの構成で何が違うかを並べた表です。最初に見るのは1行目のビルド定義と、の有無です。この表は両端の2例で、 で WAR を作る形などの中間もあります。
見るもの Ant + WAR (shop/) Spring Boot (雛形)ビルド定義 build.xml pom.xml、または build.gradle + settings.gradleラッパー 無し (Ant を別途入れる) mvnw / .mvn/wrapper/、または gradlew / gradle/wrapper/依存 JAR リポジトリ内の lib/*.jar (11本を手で置く) プロジェクト内に無い (pom.xml に座標だけ)ソースの位置 src/jp/co/... (build.xml の srcdir で決める) src/main/java/com/... (Maven の規約)設定ファイル WebContent/WEB-INF/web.xml ほか XML 2つ src/main/resources/application.properties静的ファイル WebContent/ 直下 src/main/resources/static/main メソッド 無い DemoApplication.java (@SpringBootApplication)ビルドの出力 build/classes/、dist/shop.war target/ (Maven)、build/ (Gradle)動かし方 WAR を Tomcat の webapps/ に置く java -jar
3WAR の入口は web.xml
WAR の構成では、Tomcat がこの を読んで を起こします。listener の行と servlet の行が、それぞれ Spring の部品の入れ物を1つずつ作ります。 の /app/* が URL の途中に入るので、このアプリの URL は /shop/app/hello になりました。
<?xml version="1.0" encoding="UTF-8"?><web-app xmlns="https://jakarta.ee/xml/ns/jakartaee"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation="https://jakarta.ee/xml/ns/jakartaee https://jakarta.ee/xml/ns/jakartaee/web-app_6_1.xsd"version="6.1"><!-- root context: service layer --><context-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/applicationContext.xml</param-value></context-param><listener><listener-class>org.springframework.web.context.ContextLoaderListener</listener-class></listener><!-- servlet context: web layer --><servlet><servlet-name>dispatcher</servlet-name><servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class><init-param><param-name>contextConfigLocation</param-name><param-value>/WEB-INF/dispatcher-servlet.xml</param-value></init-param><load-on-startup>1</load-on-startup></servlet><servlet-mapping><servlet-name>dispatcher</servlet-name><url-pattern>/app/*</url-pattern></servlet-mapping></web-app>
4起動の向きをログで比べる
上は WAR を Tomcat に置いたときのログで、Tomcat が WAR を見つけてから Spring のが作られています。下は(雛形に HelloController を1つ足したもの)のログで、自分の DemoApplication が先に始まり、その中で Tomcat が起動しています。誰が誰を起こすかが逆です。時間の値は極小のアプリでの1回の値で、両者の比較には使えません。
# WAR を Tomcat の webapps/ に置いたとき(Tomcat のログ。時刻の日付部分を省略)22:28:03.388 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deploying web application archive [/usr/local/tomcat/webapps/shop.war]22:28:03.729 INFO [main] org.springframework.web.context.ContextLoader.initWebApplicationContext Root WebApplicationContext: initialization started22:28:03.867 INFO [main] org.springframework.web.context.ContextLoader.initWebApplicationContext Root WebApplicationContext initialized in 138 ms22:28:03.881 INFO [main] org.springframework.web.servlet.DispatcherServlet.initServletBean Initializing Servlet 'dispatcher'22:28:04.004 INFO [main] org.springframework.web.servlet.DispatcherServlet.initServletBean Completed initialization in 123 ms22:28:04.007 INFO [main] org.apache.catalina.startup.HostConfig.deployWAR Deployment of web application archive [/usr/local/tomcat/webapps/shop.war] has finished in [619] ms22:28:04.012 INFO [main] org.apache.catalina.startup.Catalina.start Server startup in [644] milliseconds# Spring Boot の実行可能 JAR(右端を省略)$ java -jar target/demo-0.0.1-SNAPSHOT.jar... INFO 1 --- [demo] [main] com.example.demo.DemoApplication : Starting DemoApplication v0.0.1-SNAPSHOT using Java 25.0.4.1 with PID 1... INFO 1 --- [demo] [main] o.s.boot.tomcat.TomcatWebServer : Tomcat initialized with port 8080 (http)... INFO 1 --- [demo] [main] o.s.boot.tomcat.TomcatWebServer : Tomcat started on port 8080 (http) with context path '/'... INFO 1 --- [demo] [main] com.example.demo.DemoApplication : Started DemoApplication in 0.657 seconds (process running for 0.891)
5成果物の中身を比べる
WAR は自分のを に、依存の JAR を に入れます。 の実行可能 JAR は と に入れ、も持ちます。どちらも、パッケージ名どおりの階層がそのまま中に入っています。
$ ls -l dist/shop.war && jar tf dist/shop.war-rw-r--r-- 1 root root 7825305 Oct 1 22:28 dist/shop.warMETA-INF/META-INF/MANIFEST.MFWEB-INF/WEB-INF/web.xmlWEB-INF/applicationContext.xmlWEB-INF/dispatcher-servlet.xmlindex.htmlWEB-INF/classes/WEB-INF/classes/jp/WEB-INF/classes/jp/co/WEB-INF/classes/jp/co/example/WEB-INF/classes/jp/co/example/shop/WEB-INF/classes/jp/co/example/shop/service/WEB-INF/classes/jp/co/example/shop/web/WEB-INF/classes/jp/co/example/shop/service/GreetingService.classWEB-INF/classes/jp/co/example/shop/web/HelloController.classWEB-INF/lib/WEB-INF/lib/commons-logging-1.3.5.jar...(WEB-INF/lib/ に JAR が計11本)$ jar tf target/demo-0.0.1-SNAPSHOT.jar (BOOT-INF/lib/ の中身とローダのクラスを除く。抜粋)META-INF/MANIFEST.MForg/springframework/boot/loader/BOOT-INF/classes/com/example/demo/DemoApplication.classBOOT-INF/classes/com/example/demo/HelloController.classBOOT-INF/classes/application.propertiesBOOT-INF/lib/...(BOOT-INF/lib/ に JAR が計34本)