Spring Boot 01: how main becomes an HTTP application
Why does opening a URL call a Java method after the terminal prints Started? Building, starting the application, and dispatching HTTP requests are separate steps. This lesson connects them without requiring database knowledge.
Separate Maven, Spring, and Boot
Maven reads pom.xml to resolve dependencies, compile, test, and package. Spring Framework manages objects and supplies MVC and transaction facilities at runtime. Boot adds integration conventions, auto-configuration, and startup support. Changing dependency versions changes the build inputs; it does not establish correct runtime behavior.
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-parent</artifactId><version>3.5.16</version><relativePath/></parent>
<groupId>com.keeponfirst</groupId><artifactId>boot-learning-lab</artifactId><version>1.0.0</version>
<properties><java.version>21</java.version></properties>
<dependencies>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-validation</artifactId></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-jdbc</artifactId></dependency>
<dependency><groupId>com.h2database</groupId><artifactId>h2</artifactId><scope>runtime</scope></dependency>
<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-test</artifactId><scope>test</scope></dependency>
</dependencies>
<build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId></plugin></plugins></build>
</project>The parent pins Boot 3.5.16 and java.version selects Java 21. Web supplies MVC and the default embedded server; validation, JDBC, and H2 support later lessons. Test dependencies stay in test scope. Dependency management does not add every library automatically: starters still need declarations. The Boot plugin repackages the executable application.
Find the entry point and scan boundary
// LabApplication.java
package com.keeponfirst.bootlab;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
@SpringBootApplication
@EnableConfigurationProperties(LabProperties.class)
public class LabApplication {
public static void main(String[] args) {
SpringApplication.run(LabApplication.class, args);
}
}SpringApplication.run creates and starts the application context. @SpringBootApplication combines configuration, scanning, and auto-configuration entry points. This lab keeps its main class and components under com.keeponfirst.bootlab. Moving a controller into an unrelated top-level package can place it outside the default scan.
main starts one application in a JVM; it does not run again for each HTTP request. This standalone Web application starts an embedded server. An EAP-deployed WAR has a different startup path, which lesson 6 compares.
Read just the ping method
@GetMapping("/ping")
public Map<String, String> ping() {
return Map.of("service", properties.label());
}This excerpt belongs to TicketController. Its class-level /api mapping combines with /ping to form /api/ping. @RestController sends the return value through a message converter; the Map becomes JSON. properties.label() currently comes from lab.label in application.properties, explored in lesson 3.
Exercise: start it and inspect HTTP
java -version
mvn -version
mvn package
java -jar target/boot-learning-lab-1.0.0.jar
# In another terminal:
curl -i http://127.0.0.1:8080/api/pingDownload the lab and enter the directory containing pom.xml. Both java and mvn should report JDK 21; resolve a mismatch before building. Expect 200 with {"service":"boot-lab"}. Stop the application with Ctrl+C and repeat the call: the connection should fail, confirming which process served it.
| Symptom | First check |
|---|---|
| Compilation failure | Maven JDK and first compiler error |
| Port in use | Your previous process or another unused port |
| Connection refused | Running process, address, and port |
| 404 | /api prefix, mapping, component scan |
Check yourself: does editing Java immediately change curl results?
Predict what happens if you edit the ping key but only repeat curl against the running JAR. This lab does not reload that change automatically: stop, package, and start the new artifact. IDE reload and DevTools are separate mechanisms not enabled here. Match the running artifact to the source change before interpreting results.
Download the complete ticket API lab (ZIP)Next: 02: Beans, injection, auto-configuration