Java Academy

Master Java Development

Menu

Core Java

Servlets

JDBC

Microservices

Build Tools

APIs

Microservices · Lesson 3

Spring Boot Basics

What is Spring Boot?

Spring Boot is a framework that simplifies building production-ready Java applications. It provides sensible defaults, auto-configuration, and embedded servers (no need to deploy to Tomcat separately). Spring Boot makes it trivial to create REST APIs, web applications, and microservices. Instead of writing boilerplate XML configuration, you write business logic; Boot configures the rest automatically. Spring Boot has become the standard for Java microservices development.

Creating a Spring Boot Application

A Spring Boot application is remarkably simple to set up. Use Spring Initializr (start.spring.io) to generate a project with dependencies you need. Add a @SpringBootApplication annotation to a class with a main() method, and your application is ready. Spring Boot starts an embedded Tomcat server automatically on port 8080.

// Simple Spring Boot application
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
        // Embedded Tomcat starts automatically
    }
}

// Define REST endpoints
@RestController
public class HelloController {
    @GetMapping("/")
    public String hello() {
        return "Hello, Spring Boot!";
    }
    
    @GetMapping("/api/status")
    public Status getStatus() {
        return new Status("active", "All systems operational");
    }
}

class Status {
    private String status;
    private String message;
    
    Status(String status, String message) {
        this.status = status;
        this.message = message;
    }
    
    public String getStatus() { return status; }
    public String getMessage() { return message; }
}

// pom.xml dependencies
/*
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>
*/

Dependency Injection and Annotations

Spring Boot uses dependency injection to wire components together. Instead of creating objects manually, you declare dependencies with @Autowired, and Spring provides them. Common annotations: @Component (generic component), @Service (business logic), @Repository (database access), @RestController (REST endpoints). This decouples components, making code testable and maintainable.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.stereotype.Repository;

// Database access layer
@Repository
public class UserRepository {
    public User findById(int id) {
        // Query database
        return new User(id, "Alice", "alice@example.com");
    }
    
    public void save(User user) {
        // Insert into database
    }
}

// Business logic layer
@Service
public class UserService {
    @Autowired
    private UserRepository userRepository;  // Injected by Spring
    
    public User getUserById(int id) {
        return userRepository.findById(id);
    }
    
    public void registerUser(String name, String email) {
        User user = new User(0, name, email);
        userRepository.save(user);
    }
}

// REST controller
@RestController
public class UserController {
    @Autowired
    private UserService userService;  // Injected by Spring
    
    @GetMapping("/users/{id}")
    public User getUser(@PathVariable int id) {
        return userService.getUserById(id);
    }
}

class User {
    int id;
    String name;
    String email;
    
    User(int id, String name, String email) {
        this.id = id;
        this.name = name;
        this.email = email;
    }
    
    // Getters...
    public int getId() { return id; }
    public String getName() { return name; }
    public String getEmail() { return email; }
}

Configuration and Properties

Spring Boot reads configuration from application.properties or application.yml. Configure database connections, server port, logging levels, and custom settings without changing code. Use profiles (application-dev.properties, application-prod.properties) for environment-specific configuration.

# application.yml
spring:
  application:
    name: my-service
  server:
    port: 8080
    servlet:
      context-path: /api
  datasource:
    url: jdbc:mysql://localhost:3306/myapp
    username: root
    password: password
    driver-class-name: com.mysql.cj.jdbc.Driver
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: false
logging:
  level:
    root: INFO
    com.example: DEBUG
  file: logs/application.log
app:
  version: 1.0.0
  debug: false
// Access properties in code
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

@Component
public class AppConfig {
    @Value("${app.version}")
    private String appVersion;
    
    @Value("${spring.application.name}")
    private String appName;
    
    public void printConfig() {
        System.out.println("App: " + appName + " v" + appVersion);
    }
}

Embedded Database and H2

For development and testing, Spring Boot can use H2, an in-memory SQL database. No external database setup needed — perfect for learning and quick testing. Just add the dependency; Spring Boot auto-configures it.

// pom.xml
/*
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <scope>runtime</scope>
</dependency>

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-jpa</artifactId>
</dependency>
*/

// Entity
import javax.persistence.*;

@Entity
@Table(name = "users")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    
    @Column(length = 100)
    private String name;
    
    @Column(unique = true, length = 100)
    private String email;
    
    // Getters and setters...
}

// Repository (Spring Data JPA)
import org.springframework.data.jpa.repository.JpaRepository;

public interface UserRepository extends JpaRepository<User, Integer> {
    User findByEmail(String email);
}

// Usage in service
@Service
public class UserService {
    @Autowired
    private UserRepository repository;
    
    public User getUserByEmail(String email) {
        return repository.findByEmail(email);
    }
}

// application.properties for H2
/*
spring.datasource.url=jdbc:h2:mem:testdb
spring.datasource.driverClassName=org.h2.Driver
spring.jpa.database-platform=org.hibernate.dialect.H2Dialect
spring.h2.console.enabled=true
*/
Spring Boot FeaturePurposeExample
@SpringBootApplicationEnables auto-configurationMain class annotation
@RestControllerDefines REST endpointsHTTP request handlers
@ServiceBusiness logic component@Service + Injected into controllers
@RepositoryData access componentInjected into services
@AutowiredDependency injectionSpring provides the dependency
application.ymlConfigurationDatabase, port, logging settings

Common Mistake: Over-using @Autowired in places where you should just new() an object. Dependency injection is powerful for dependencies that need to be mocked in tests or swapped at runtime. For simple value objects or utilities, just instantiate them directly. Also, avoid circular dependencies — if ServiceA injects ServiceB and ServiceB injects ServiceA, Spring can't wire them. Refactor to break the cycle.

Best Practices for Spring Boot

  • Use dependency injection for components that need testing or flexibility
  • Externalize configuration to application.yml; don't hardcode
  • Use profiles (dev, test, prod) for environment-specific settings
  • Let Spring handle HTTP status codes — return appropriate HTTP codes
  • Use Spring Data JPA for database access; it eliminates boilerplate
  • Enable logging at appropriate levels; log errors and important events
  • Use embedded H2 for development/testing; switch to real database in production
  • Test with Spring Boot Test and @SpringBootTest annotation

Real-World Example: Microservice Built with Spring Boot

A User Service microservice is created with Spring Boot in minutes. It defines User entity with JPA annotations, UserRepository extending JpaRepository, UserService with business logic, and UserController with REST endpoints. Configuration is in application.yml: server port, database URL, logging level. On startup, Spring Boot auto-configures Hibernate, creates database tables, and starts embedded Tomcat. Dependency injection wires UserService into UserController automatically. Running mvn spring-boot:run starts the service; tests use @SpringBootTest with an in-memory H2 database. The result: a production-ready microservice with minimal boilerplate code.

Quiz Check

Quick Knowledge Test

Loading quiz questions...