Project shape
Three files are enough for the first run.
orders/
├── pom.xml
└── src/main/
├── java/com/example/orders/
│ └── OrdersApplication.java
└── resources/
└── application.propertiesThe application class sits in the root package com.example.orders. Later components should live in that package or one of its subpackages so the default scan can find them.
Maven's standard layout separates Java source from runtime resources. Package names belong to Java; folders mirror those packages. Properties are resources placed on the classpath, so they live below src/main/resources rather than inside a Java package.
Java source
Compiled into bytecode. Classes, interfaces, records and annotations live below src/main/java.
Resources
Copied into the application classpath. Configuration, templates and static files can live below src/main/resources.
Maven responsibilities
The parent supplies build defaults; the starter supplies libraries.
spring-boot-starter-parent
A Maven parent that provides compatible dependency versions, plugin management and sensible compiler/resource defaults. It is not a jar added to the running application.
spring-boot-starter
A dependency bundle for core Boot support, auto-configuration and logging. It does not include the servlet stack required for an HTTP server.
spring-boot-maven-plugin
Builds an executable Boot jar and provides Maven goals such as spring-boot:run.
These three entries solve different build problems. The parent controls Maven defaults, the starter contributes dependencies to the application classpath, and the plugin changes how the application is run and packaged. Removing one does not mean the other two take over its job.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<!-- No version here -->
</dependency>The starter version is omitted because the Boot parent manages a tested set of versions. If every Spring library were versioned independently, Maven could resolve a combination that compiles poorly or fails at runtime.
The application annotation
@SpringBootApplication combines three roles.
@Configuration
The class may contribute bean definitions and application configuration.
@EnableAutoConfiguration
Boot evaluates available classes, existing beans and configuration to decide which infrastructure it can provide.
@ComponentScan
Spring searches the application class package and its subpackages for component classes.
Conceptually, the composed annotation gives the application class the same three roles as the explicit form below:
@Configuration
@EnableAutoConfiguration
@ComponentScan
public class OrdersApplication {
// ...
}Use @SpringBootApplication for the normal entry point. The expanded form is useful for understanding, not a recommendation to replace the composed annotation in every project.
package com.example.orders;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrdersApplication {
public static void main(String[] args) {
SpringApplication.run(OrdersApplication.class, args);
}
}SpringApplication.run(...) creates and refreshes an ApplicationContext. The method returns the context, but normal business code receives beans through injection instead of retrieving them manually.
Startup, step by step
SpringApplication.run builds and refreshes the container.
- 01
Inspect the classpath
Boot determines whether this looks like a servlet web application, reactive web application or non-web application.
- 02
Prepare the environment
Command-line arguments, system values and application properties become available as configuration.
- 03
Create the appropriate ApplicationContext
This project gets a non-web context because no servlet or reactive web application stack is present.
- 04
Load bean definitions
The application configuration, component scan results and matching auto-configurations contribute recipes for objects.
- 05
Refresh the context
Spring creates non-lazy singleton beans, resolves constructor dependencies and runs lifecycle callbacks.
- 06
Run startup callbacks
Boot invokes
CommandLineRunnerandApplicationRunnerbeans after successful startup.
This is why a missing dependency usually prevents startup: the context must build a complete valid graph before the application begins normal work.
The scan boundary
The application class location is an architectural decision.
com.example.orders
├── OrdersApplication // scan starts here
├── notification
│ └── EmailNotificationSender // included
├── service
│ └── OrderService // included
└── runner
└── DemoRunner // included
com.example.payments
└── PaymentService // not included@ComponentScan begins with the package containing OrdersApplication. It walks downward through subpackages; it does not walk upward to com.example and then down into sibling packages.
Good default
Put the application class at the root of one application's packages, then group features below it.
Common surprise
A correctly annotated service outside the root is still invisible to the default scan.
Predict startup behaviour
No servlet classes means no embedded web server.
Auto-configuration reacts to what is available. With only spring-boot-starter, Boot creates a non-web application context, logs that the application started and then exits when no non-daemon work remains. Adding web libraries later changes the conditions that match.
| Dependencies | Application type | Typical result |
|---|---|---|
spring-boot-starter | Non-web | Creates the context; no HTTP port is opened. |
spring-boot-starter-webmvc | Servlet web | Configures Spring MVC and normally starts an embedded servlet server. |
| Reactive web starter | Reactive web | Creates reactive web infrastructure when its conditions match. |
@SpringBootApplication is present in all three cases. The annotation does not mean “start Tomcat.” It enables conditional configuration; the classpath supplies evidence about which kind of application is being built.
The first property
application.properties changes configuration, not Java structure.
spring.application.name=ordersThe application name can appear in logging, metrics and other infrastructure. It does not rename the Java class, Maven artifact or package. Those are separate identities that happen to use a consistent name in this example.
Maven artifact: orders
Java class: OrdersApplication
Java package: com.example.orders
Spring property: spring.application.name=ordersPractice checkpoint
Write it before reading the solution.
From an empty directory, create a minimal Maven Spring Boot application named orders.
- Use Spring Boot 4.1.1 and Java 17.
- Do not add a web dependency.
- Use the package
com.example.orders. - Set the application name in properties.
Hints, in increasing order
- Use Java 17 and Spring Boot 4.1.1 as this series' fixed baseline.
- The only runtime starter needed is
spring-boot-starter. - Keep the application class in
com.example.ordersand give its file the exact public class name.
Working solution
<?xml version="1.0" encoding="UTF-8"?>
<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>4.1.1</version>
<relativePath/>
</parent>
<groupId>com.example</groupId>
<artifactId>orders</artifactId>
<version>0.0.1-SNAPSHOT</version>
<properties>
<java.version>17</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</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>package com.example.orders;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrdersApplication {
public static void main(String[] args) {
SpringApplication.run(OrdersApplication.class, args);
}
}spring.application.name=ordersRun with mvn spring-boot:run. A successful startup does not include Tomcat, Jetty or Netty because no web stack is present.
Elapsed time · hint level (H0 means no hint; H1–Hn is the last hint used) · conceptual errors · mechanical errors · explanation confidence from 0–2.
Foundation check
Where will Spring scan?
With the application class in com.example.orders, the default scan covers that package and its subpackages. A component in com.example.payments is outside that boundary.