Creating a Spring Boot Project
Creating a Spring Boot Project
Every Spring Boot application starts from the same three artefacts: a generated project skeleton from Spring Initializr, a well-defined directory layout, and a single annotated main class that bootstraps the entire framework. This lesson dissects all three so you understand not just what exists, but why it exists and what you can safely change.
Spring Initializr — Your Project Generator
start.spring.io is the official, browser-based project generator maintained by the Spring team. It produces a ready-to-import archive in seconds. The same generation is available inside IntelliJ IDEA (File → New → Project → Spring Initializr) and VS Code (Spring Boot Extension Pack). All three hit the same REST API under the hood.
The key choices you make on the form:
- Project type: Maven or Gradle (Groovy/Kotlin DSL). Maven is the safer default for teams; Gradle builds are faster for large monorepos.
- Language: Java (this course), Kotlin, or Groovy.
- Spring Boot version: always pick the latest GA (generally available) release. As of Spring Boot 3.x, the minimum Java version is 17.
- Group / Artifact / Name / Description: standard Maven coordinates. Use a reverse-domain group such as
com.acmeand a lowercase, hyphenated artifact such asbookstore-api. - Packaging: Jar for most applications (the embedded server is bundled). Choose War only when you must deploy to an external servlet container.
- Java version: match your JDK. 21 (LTS) is the current best choice.
- Dependencies (starters): add what you need now; you can always add more to
pom.xmllater.
Click Generate, unzip the archive, and open it in your IDE. The project compiles and runs out of the box — there is nothing to configure before the first ./mvnw spring-boot:run.
The Standard Project Layout
Spring Initializr produces a Maven or Gradle project that follows the standard Java directory convention. A freshly generated project looks like this:
A few points worth noting:
- The Maven Wrapper (
mvnw) pins a specific Maven version for the project, so every developer and every CI server uses exactly the same build tool version without a local installation. Run it as./mvnw spring-boot:runon macOS/Linux ormvnw.cmd spring-boot:runon Windows. src/main/resources/static/is served directly by the embedded web server. A file atstatic/favicon.icois reachable athttp://localhost:8080/favicon.ico.src/main/resources/templates/is the default location for server-side view templates. It only matters if you add a templating engine starter.- The test source tree mirrors the main tree. The generated
BookstoreApiApplicationTestsloads the full Spring context — it is an integration smoke-test, not a unit test.
@Component, @Service, @Repository, @Controller, etc.) starting from the package that contains the main class, and all sub-packages beneath it. Put your main class at the root of your base package — not inside a sub-package — so the scan covers everything automatically.
The pom.xml — What Initializr Generates
The generated pom.xml has two structural additions beyond a plain Maven project: it inherits from spring-boot-starter-parent and it includes the Spring Boot Maven plugin.
The spring-boot-starter-parent imports the Spring Boot BOM (Bill of Materials), which defines managed versions for hundreds of libraries. That is why your <dependency> entries need no <version> tag — the BOM supplies a tested, compatible version automatically. The Maven plugin adds the spring-boot:run goal and, crucially, repackages the JAR into an executable fat JAR that bundles every dependency so you can deploy it with a single java -jar command.
The Main Class — @SpringBootApplication
Spring Initializr generates exactly one main class. It is tiny but packs a lot of meaning:
@SpringBootApplication is a composed annotation — a shorthand for three annotations applied together:
@SpringBootConfiguration— marks this class as a configuration source (equivalent to Spring's@Configuration). You can define@Beanmethods directly here, though most teams keep the main class clean and put beans in dedicated@Configurationclasses.@EnableAutoConfiguration— tells Spring Boot to inspect the classpath and activate sensible default configuration for whatever it finds. Ifspring-boot-starter-webis on the classpath, it configures an embedded Tomcat and aDispatcherServlet. Auto-configuration is covered in depth in Lesson 4.@ComponentScan— scans the current package (and sub-packages) for Spring-managed components. This is the mechanism that discovers your@Service,@Repository, and@RestControllerclasses.
SpringApplication.run(BookstoreApiApplication.class, args) performs the actual bootstrap:
- Creates an
ApplicationContextappropriate for the detected environment (servlet vs reactive vs none). - Registers all discovered beans and applies auto-configuration.
- Starts the embedded server (if a web starter is present).
- Fires
ApplicationReadyEventso listeners and runners can execute post-startup logic.
com.acme.bookstoreapi.config, the @ComponentScan will only scan com.acme.bookstoreapi.config and its children — missing beans in sibling packages. Either keep the main class at the root, or explicitly configure @SpringBootApplication(scanBasePackages = "com.acme.bookstoreapi").
Running the Application
You have three equivalent ways to start the app during development:
- Maven Wrapper:
./mvnw spring-boot:run— compiles and starts in one command, convenient for quick iteration. - IDE run configuration: right-click the main class → Run. IntelliJ IDEA and VS Code both detect Spring Boot apps and create ready-made run configurations automatically.
- Fat JAR:
./mvnw packagethenjava -jar target/bookstore-api-0.0.1-SNAPSHOT.jar— this is the production deployment model.
With spring-boot-starter-web on the classpath you will see output like the following and the application will be listening on port 8080:
Summary
Spring Initializr generates a Maven or Gradle project with a fixed, conventional layout. The main class, annotated with @SpringBootApplication, owns component scanning, auto-configuration activation, and the bootstrap entry point all in one place. Understanding this scaffolding — and the choices baked into it — means you can modify it deliberately rather than by trial and error. In the next lesson you will explore how starters and the BOM keep dependency management under control.