Lesson 11: Spring Boot Introduction
Discover Spring Boot: the framework that simplifies Java web development with auto-configuration, dependency injection, and powerful conventions that help you build production-ready applications quickly.
Introduction
Building enterprise Java applications traditionally required extensive configuration, complex setup procedures, and countless hours of boilerplate code before you could write your first meaningful line of business logic. Spring Boot revolutionizes this experience by providing smart defaults, automatic configuration, and powerful conventions that eliminate most of the tedious setup work. Think of Spring Boot as having a highly experienced Java developer sitting next to you, automatically handling all the mundane configuration tasks while you focus on solving business problems. It provides embedded web servers, production-ready features like health checks and metrics, and a rich ecosystem of starter dependencies that bring in exactly what you need with minimal effort. Whether you're building REST APIs, web applications, or microservices, Spring Boot accelerates development without sacrificing the power and flexibility that makes Java great for enterprise applications. This lesson introduces you to Spring Boot's core concepts and shows you how to build your first application with surprisingly little code.
What is Spring Boot
Definition
Spring Boot is an opinionated framework built on top of the Spring Framework that simplifies the creation of production-ready Java applications. It provides auto-configuration, embedded servers, and starter dependencies that eliminate most boilerplate configuration. Spring Boot follows the "convention over configuration" principle, making intelligent assumptions about what you want to do and configuring your application accordingly. It doesn't generate code or require XML configuration - instead, it uses annotations and sensible defaults to set everything up automatically. The framework includes production features like health checks, metrics, and externalized configuration out of the box.
Analogy
Think of Spring Boot like a modern smart home system compared to building a house from scratch with individual electrical, plumbing, and security components. In the old days (traditional Spring), you had to manually wire every light switch, configure each outlet, set up the security system, and connect all the plumbing - a time-consuming process requiring deep knowledge of every system. Spring Boot is like a smart home kit that comes pre-configured: when you say "I want a three-bedroom house," it automatically includes appropriate lighting, standard plumbing, basic security, and climate control without you having to specify every detail. You can still customize everything if needed, but the smart defaults handle 90% of common requirements. The house is move-in ready much faster, yet you retain full control over customization when you need it. Both approaches result in a fully functional home, but Spring Boot gets you there much faster with much less manual work.
Examples
Traditional Spring vs Spring Boot application startup:
// Traditional Spring - lots of configuration required
// Multiple XML files, manual server setup, dependency management
// Spring Boot - minimal code needed
@SpringBootApplication
public class MyApplication {
public static void main(String[] args) {
SpringApplication.run(MyApplication.class, args);
}
}
Automatic web server inclusion:
// No need to deploy to external Tomcat
// Embedded server starts automatically
// Application runs on http://localhost:8080 by default
mvn spring-boot:run // Start the application
Database connectivity with zero configuration:
// Add H2 database dependency to pom.xml
// Spring Boot automatically configures database connection
// No XML configuration files needed
@Entity
public class User {
@Id @GeneratedValue
private Long id;
private String name;
}
REST endpoint in seconds:
@RestController
public class HelloController {
@GetMapping("/hello")
public String hello() {
return "Hello, Spring Boot!"; // Accessible at /hello endpoint
}
}
Spring Boot Benefits
Definition
Spring Boot eliminates configuration overhead, provides embedded servers for easy deployment, includes production-ready features, offers extensive starter dependencies, and enables rapid prototyping and development. It reduces development time by up to 70% compared to traditional Spring applications while maintaining enterprise-grade robustness and scalability. The framework's opinionated approach means most applications work perfectly with default settings, but everything remains customizable when needed.
Analogy
Spring Boot benefits are like switching from cooking everything from scratch to having a well-equipped kitchen with smart appliances and pre-made quality ingredients. Instead of spending hours preparing basic components (grinding spices, making stock, preparing sauces), you can focus on creating the actual dish. The smart oven (auto-configuration) knows the right temperature for different foods, the refrigerator (embedded server) is already stocked with essentials, and you have access to premium ingredients (starter dependencies) that work perfectly together. You can still make everything from scratch when you want full control (custom configuration), but for most meals, the smart kitchen handles the tedious work while you focus on the creative cooking. The result is faster meal preparation without sacrificing quality, and your kitchen is always ready for dinner parties (production deployment) without additional setup.
Examples
Rapid development - working REST API in minutes:
@RestController
public class BookController {
@GetMapping("/books")
public List getBooks() {
return List.of("Java Guide", "Spring Mastery", "Boot Essentials");
}
}
Zero deployment complexity:
// Build fat JAR with embedded server
mvn package
// Run anywhere with Java installed
java -jar myapp.jar
// No Tomcat installation or configuration needed
Production features included:
// Health check endpoint automatically available
// GET /actuator/health returns application status
// Metrics, logging, monitoring built-in
management.endpoints.web.exposure.include=health,metrics
Database integration with minimal code:
public interface BookRepository extends JpaRepository {
List findByAuthor(String author); // Query method automatically implemented
}
// Spring Boot auto-configures database, connection pool, transactions
External configuration without code changes:
// application.properties automatically loaded
server.port=8081
spring.datasource.url=jdbc:mysql://localhost/mydb
// Values injected into application without rebuilding
Project Setup
Definition
Spring Boot projects can be created using Spring Initializr (start.spring.io), IDE plugins, or command-line tools. The setup includes choosing the build tool (Maven or Gradle), Java version, dependencies, and project metadata. Spring Initializr generates a ready-to-run project with proper directory structure, build configuration, and starter dependencies. The generated project includes a main application class with @SpringBootApplication annotation and is immediately runnable.
Analogy
Creating a Spring Boot project is like using a modern app store to set up a new smartphone. Instead of manually installing an operating system, configuring drivers, and hunting down compatible apps, you choose your phone model (Java version), select the apps you want (dependencies), and everything is downloaded and configured automatically. Spring Initializr is like the app store - you specify what you need (web development, database access, security) and it creates a perfectly configured "phone" ready to use. Within minutes, you have a working device with all your chosen apps properly integrated and ready to use. You can always install more apps later (add dependencies) or customize settings (modify configuration), but you start with a fully functional setup rather than a blank device.
Examples
Creating project with Spring Initializr:
// Visit start.spring.io
// Choose: Maven, Java 17, Spring Boot 3.x
// Add dependencies: Spring Web, Spring Data JPA
// Generate and download zip file
Generated project structure:
src/main/java/com/example/demo/
├── DemoApplication.java // Main application class
├── controller/ // REST controllers
├── service/ // Business logic
├── repository/ // Data access
└── model/ // Entity classes
Main application class (auto-generated):
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
Maven dependencies (auto-configured):
org.springframework.boot
spring-boot-starter-web
Running the application:
// Command line
./mvnw spring-boot:run
// IDE: Right-click DemoApplication.java -> Run
// Application starts on http://localhost:8080
Auto-Configuration
Definition
Auto-configuration is Spring Boot's intelligent system that automatically configures your application based on the dependencies you've added to your classpath. It uses conditional logic to determine what beans to create and how to configure them. For example, if it finds H2 database on the classpath, it automatically configures an in-memory database. If it sees Spring MVC dependencies, it sets up web components. Auto-configuration can be customized or disabled when you need specific behavior, but it works perfectly for most common scenarios.
Analogy
Auto-configuration is like a smart personal assistant who observes what tools you bring to work and automatically sets up your workspace accordingly. If you bring a laptop, they set up a desk with power outlet and wifi. If you bring art supplies, they arrange proper lighting and ventilation. If you bring cooking ingredients, they prepare a kitchen workspace with appropriate utensils and equipment. The assistant makes intelligent decisions based on what they see, but you can always override their choices or request specific arrangements. They don't ask you a hundred questions about every detail - they use experience and common sense to create a productive environment, while remaining flexible when you have special requirements. This is exactly how Spring Boot's auto-configuration works: it sees your dependencies (tools) and intelligently sets up the application environment.
Examples
Database auto-configuration:
// Add H2 dependency - Spring Boot automatically:
// - Creates DataSource bean
// - Configures in-memory database
// - Sets up JPA entity manager
// No configuration code needed
Web server auto-configuration:
// Add spring-boot-starter-web - automatically configures:
// - Embedded Tomcat server
// - Spring MVC framework
// - JSON message converters
// - Error handling
@RestController // This annotation triggers web auto-configuration
public class ApiController { }
Conditional configuration in action:
// Spring Boot checks: "Is there a DataSource bean?"
// If no: Creates default DataSource
// If yes: Uses your custom DataSource
@ConditionalOnMissingBean(DataSource.class)
public DataSource defaultDataSource() {
// Only created if no DataSource exists
}
Viewing auto-configuration report:
// Add to application.properties
logging.level.org.springframework.boot.autoconfigure=DEBUG
// Shows what got auto-configured and why
// Helps understand what Spring Boot is doing
Excluding auto-configuration when needed:
@SpringBootApplication(exclude = {DataSourceAutoConfiguration.class})
public class MyApp {
// Disables automatic database configuration
// Useful when you want full manual control
}
Dependency Injection Basics
Definition
Dependency Injection (DI) is a design pattern where Spring Boot automatically provides (injects) objects that your classes need, rather than your classes creating them directly. You mark classes with @Component, @Service, or @Repository annotations, and Spring Boot manages their lifecycle and dependencies. When a class needs another object, you can inject it using @Autowired annotation or constructor injection. This creates loose coupling between components and makes testing easier because dependencies can be easily mocked or replaced.
Analogy
Dependency injection is like having a personal assistant who anticipates your needs and brings you exactly what you require for each task. Instead of you having to leave your desk to find a calculator, printer, or reference books every time you need them, your assistant observes what you're working on and silently places the right tools on your desk before you even ask. When you're writing a report, the assistant brings you a laptop, research materials, and a coffee. When you're doing math, they bring a calculator and graph paper. You don't have to know where these items are stored or how to set them up - you just use them. Similarly, Spring Boot's dependency injection observes what each part of your application needs and automatically provides the right objects (services, repositories, configurations) without your code having to create or find them manually.
Examples
Creating injectable components:
@Service
public class BookService {
public List getAllBooks() {
return List.of(new Book("Spring Boot Guide"));
}
}
Constructor injection (recommended approach):
@RestController
public class BookController {
private final BookService bookService;
public BookController(BookService bookService) {
this.bookService = bookService; // Spring Boot injects BookService
}
}
Field injection with @Autowired:
@RestController
public class BookController {
@Autowired
private BookService bookService; // Spring Boot injects automatically
@GetMapping("/books")
public List getBooks() {
return bookService.getAllBooks();
}
}
Repository injection example:
@Service
public class UserService {
private final UserRepository userRepository;
public UserService(UserRepository userRepository) {
this.userRepository = userRepository; // Spring Boot injects repository
}
public User findById(Long id) {
return userRepository.findById(id).orElse(null);
}
}
Component scanning in action:
@SpringBootApplication // Automatically scans for @Component, @Service, @Repository
public class MyApp {
// Spring Boot finds and manages all annotated classes
// Creates dependency graph and injects as needed
}
Application Structure
Definition
Spring Boot applications follow a layered architecture with clear separation of concerns. Controllers handle HTTP requests and responses, Services contain business logic, Repositories manage data access, and Models represent data entities. The @SpringBootApplication annotation combines @Configuration, @EnableAutoConfiguration, and @ComponentScan to bootstrap the application. Package structure typically mirrors this layered approach, making the codebase easy to navigate and maintain.
Analogy
A Spring Boot application structure is like organizing a well-run restaurant. The front-of-house staff (Controllers) interact with customers, take orders, and serve food - they handle all customer-facing activities. The kitchen staff (Services) prepare the actual meals using recipes and business rules - they contain the core cooking logic. The storage and inventory team (Repositories) manages all the ingredients, knows where everything is stored, and handles procurement - they deal with data storage and retrieval. The menu items and ingredients (Models) represent what the restaurant offers and works with. The restaurant manager (@SpringBootApplication) coordinates all departments, ensures everyone knows their role, and keeps the operation running smoothly. Each department has clear responsibilities and communicates through established protocols, just like the layers in a Spring Boot application.
Examples
Typical package structure:
com.example.bookstore/
├── BookstoreApplication.java // Main application class
├── controller/ // HTTP request handling
├── service/ // Business logic
├── repository/ // Data access layer
├── model/ // Entity classes
└── config/ // Configuration classes
Main application class structure:
@SpringBootApplication
public class BookstoreApplication {
public static void main(String[] args) {
SpringApplication.run(BookstoreApplication.class, args);
}
}
Controller layer example:
@RestController
@RequestMapping("/api/books")
public class BookController {
private final BookService bookService;
@GetMapping
public List getAllBooks() {
return bookService.findAll(); // Delegates to service layer
}
}
Service layer example:
@Service
public class BookService {
private final BookRepository bookRepository;
public List findAll() {
return bookRepository.findAll(); // Delegates to repository
}
}
Repository layer example:
@Repository
public interface BookRepository extends JpaRepository {
List findByAuthor(String author); // Spring Data provides implementation
}
First REST Controller
Definition
A REST Controller in Spring Boot handles HTTP requests and returns responses, typically in JSON format. The @RestController annotation combines @Controller and @ResponseBody, automatically converting return values to JSON. HTTP mapping annotations like @GetMapping, @PostMapping, @PutMapping, and @DeleteMapping map specific HTTP methods to controller methods. Path variables and request parameters can be easily extracted using @PathVariable and @RequestParam annotations.
Analogy
A REST controller is like a well-trained receptionist at a busy office building. When visitors arrive with different types of requests (GET data, POST new information, PUT updates, DELETE records), the receptionist understands exactly what each person needs and directs them appropriately. They can handle questions about specific departments (path variables), take detailed forms (request bodies), and always respond in a consistent, professional format (JSON responses). The receptionist doesn't do the actual work - they coordinate with the right departments (services) and then package the results in a clear, standardized format that visitors can easily understand. Whether someone wants a simple directory listing or needs to submit a complex application, the receptionist handles the interaction smoothly and consistently.
Examples
Basic REST controller:
@RestController
public class WelcomeController {
@GetMapping("/welcome")
public String welcome() {
return "Welcome to Spring Boot!"; // Returns plain text
}
}
Returning JSON objects:
@RestController
public class UserController {
@GetMapping("/user")
public User getUser() {
return new User("Alice", "alice@example.com"); // Automatically converts to JSON
}
}
Handling path variables:
@RestController
public class BookController {
@GetMapping("/books/{id}")
public Book getBook(@PathVariable Long id) {
return new Book(id, "Spring Boot in Action"); // Extract ID from URL
}
}
Processing request parameters:
@RestController
public class SearchController {
@GetMapping("/search")
public List search(@RequestParam String title) {
return bookService.findByTitle(title); // Handle ?title=java query
}
}
Handling POST requests with request body:
@RestController
public class BookController {
@PostMapping("/books")
public Book createBook(@RequestBody Book book) {
return bookService.save(book); // JSON in request body becomes Book object
}
}
Configuration Properties
Definition
Spring Boot applications can be configured externally using properties files, YAML files, environment variables, or command-line arguments. The application.properties or application.yml files contain configuration settings that Spring Boot automatically loads and makes available throughout the application. You can inject these values using @Value annotation or create configuration classes with @ConfigurationProperties for type-safe configuration binding. This enables changing application behavior without modifying code.
Analogy
Configuration properties are like a settings panel on your smartphone or computer - they let you customize how your device behaves without needing to reprogram it. Just as you can change screen brightness, notification sounds, or default apps through settings rather than hiring a programmer, Spring Boot's configuration properties let you modify database connections, server ports, or feature flags by simply editing text files. The application reads these settings when it starts up and adjusts its behavior accordingly. You can even have different settings files for different environments (development, testing, production) just like how you might have different settings profiles on your device for work versus personal use. The beauty is that the same application code works everywhere - only the configuration changes.
Examples
Basic application.properties configuration:
server.port=8081
spring.application.name=my-bookstore
logging.level.com.example=DEBUG
management.endpoints.web.exposure.include=health,info
Injecting single properties with @Value:
@Component
public class AppConfig {
@Value("${spring.application.name}")
private String appName;
@Value("${server.port:8080}") // Default value if not set
private int serverPort;
}
Type-safe configuration with @ConfigurationProperties:
@ConfigurationProperties(prefix = "app")
@Component
public class AppProperties {
private String name;
private String version;
private Database database = new Database();
// getters and setters
}
Using configuration properties in services:
@Service
public class NotificationService {
private final AppProperties appProperties;
public void sendWelcome(User user) {
String message = "Welcome to " + appProperties.getName();
// Use configured app name in messages
}
}
Environment-specific configuration:
// application-dev.properties
spring.datasource.url=jdbc:h2:mem:devdb
// application-prod.properties
spring.datasource.url=jdbc:mysql://prod-server/mydb
// Activate with: --spring.profiles.active=prod
Spring Boot Starters
Definition
Spring Boot Starters are dependency descriptors that bring in all the libraries needed for a specific functionality. Instead of manually adding dozens of compatible dependencies, you add one starter and get everything you need. Common starters include spring-boot-starter-web for web applications, spring-boot-starter-data-jpa for database access, and spring-boot-starter-security for authentication. Starters ensure all dependencies are compatible and properly versioned, eliminating dependency hell.
Analogy
Spring Boot Starters are like buying a complete home theater system versus purchasing each component separately. When you buy a "home theater starter," you get a receiver, speakers, subwoofer, cables, remote control, and setup guide - all guaranteed to work together perfectly. You don't have to research which speakers are compatible with which receiver, or worry about whether the cables will fit the connections. Everything is tested, matched, and ready to use. If you tried to build the same system by buying individual components, you'd spend weeks researching compatibility, dealing with version mismatches, and possibly ending up with components that don't work well together. Spring Boot Starters work the same way - when you add the "web starter," you get the web server, MVC framework, JSON converters, and all supporting libraries that are tested to work perfectly together.
Examples
Web application starter:
org.springframework.boot
spring-boot-starter-web
Database access starter:
org.springframework.boot
spring-boot-starter-data-jpa
Security starter:
org.springframework.boot
spring-boot-starter-security
Testing starter:
org.springframework.boot
spring-boot-starter-test
test
What you get with minimal dependencies:
// Just adding spring-boot-starter-web gives you:
// - Embedded Tomcat server
// - Spring MVC framework
// - JSON serialization/deserialization
// - Error handling and logging
// - Static resource serving
// - Auto-configuration for all components
Profiles & Environments
Definition
Spring Boot profiles allow you to segregate parts of your application configuration and make it available only in certain environments. You can define different configurations for development, testing, and production environments using profile-specific property files. Beans can be activated only for specific profiles using @Profile annotation. This enables deploying the same application code across different environments with appropriate configurations for each.
Analogy
Spring Boot profiles are like having different modes on a camera - portrait mode, landscape mode, night mode, and sports mode. The same camera (your application) behaves differently depending on which mode is active. In portrait mode, it focuses on faces and blurs the background. In sports mode, it uses faster shutter speeds to capture motion. The core camera functionality remains the same, but the settings automatically adjust to optimize for different situations. Similarly, your Spring Boot application might use an in-memory database and detailed logging in development mode, but switch to a production database and minimal logging in production mode. The same code runs everywhere, but the behavior adapts to the environment's needs.
Examples
Profile-specific property files:
// application-dev.properties (development)
spring.datasource.url=jdbc:h2:mem:testdb
logging.level.root=DEBUG
// application-prod.properties (production)
spring.datasource.url=jdbc:mysql://prod-server/app
logging.level.root=WARN
Activating profiles:
// Command line activation
java -jar app.jar --spring.profiles.active=prod
// Environment variable
export SPRING_PROFILES_ACTIVE=dev
// application.properties default
spring.profiles.active=dev
Profile-specific beans:
@Profile("dev")
@Component
public class DevEmailService implements EmailService {
public void sendEmail(String message) {
System.out.println("DEV: Email sent - " + message);
}
}
@Profile("prod")
@Component
public class ProdEmailService implements EmailService {
public void sendEmail(String message) {
// Actually send email via SMTP
}
}
Conditional configuration based on profiles:
@Configuration
public class DatabaseConfig {
@Bean
@Profile("dev")
public DataSource devDataSource() {
return new EmbeddedDatabaseBuilder().build(); // H2 for development
}
@Bean
@Profile("prod")
public DataSource prodDataSource() {
return DataSourceBuilder.create().build(); // MySQL for production
}
}
Summary
You've now discovered how Spring Boot revolutionizes Java development by eliminating configuration overhead and providing intelligent defaults that work out of the box. From auto-configuration that sets up your application based on dependencies, to dependency injection that manages object relationships automatically, Spring Boot handles the tedious infrastructure work so you can focus on business logic. You've learned to create REST controllers, configure applications externally, leverage powerful starter dependencies, and manage different environments with profiles. These fundamentals form the foundation for building production-ready applications quickly and efficiently. Next, you'll dive deeper into Spring Boot's web development capabilities, exploring advanced request handling, data validation, and building robust REST APIs that can handle real-world requirements.
Programming Challenge
Challenge: Personal Task Management API
Task: Build a Spring Boot application that manages personal tasks with different configurations for development and production environments.
Requirements:
- Create a
Task
model class with: id, title, description, completed status, and creation date - Implement a
TaskService
that manages an in-memory list of tasks - Create a
TaskController
with REST endpoints: GET /api/tasks
- Get all tasksGET /api/tasks/{id}
- Get task by IDPOST /api/tasks
- Create new taskPUT /api/tasks/{id}
- Update taskDELETE /api/tasks/{id}
- Delete task- Use @ConfigurationProperties to configure:
- Application name and version
- Maximum tasks allowed
- Default task priority
- Create two profiles (dev and prod) with different configurations
- Implement proper dependency injection throughout the application
- Add a health check endpoint that shows app status and task count
Bonus features:
- Add task search endpoint with query parameters
- Implement task categories with profile-specific defaults
- Create a simple statistics endpoint showing completed vs pending tasks
- Add input validation for task creation and updates
Learning Goals: Practice Spring Boot fundamentals including auto-configuration, dependency injection, REST controllers, configuration properties, and profiles while building a complete, functional API.