Spring BootBeginner

Spring Boot Fundamentals: Starters, REST & Dependency Injection

Learn what Spring Boot brings to Java development: opinionated starters, auto-configuration, building REST APIs, externalized config, and core dependency injection with @Service and @Autowired.

4 sections · ~28 min · 5-question quiz (pass ≥ 70%)

1What Spring Boot Is (and Why Teams Reach for It)

Spring Boot is not a separate framework — it is an opinionated layer on top of the Spring Framework that gets you from zero to a running application fast.

Before Boot, wiring a Spring app meant pages of XML or Java config for datasources, web servers, and component scanning. Boot replaces that ceremony with:

  • Starters — curated dependency bundles (spring-boot-starter-web, spring-boot-starter-data-jpa)
  • Auto-configuration — conditional beans registered when classpath entries are present
  • Embedded servers — Tomcat/Jetty/Undertow run inside your JAR; no WAR deployment required
@SpringBootApplication  // = @Configuration + @EnableAutoConfiguration + @ComponentScan
public class EmpForgeApplication {
    public static void main(String[] args) {
        SpringApplication.run(EmpForgeApplication.class, args);
    }
}

Rule of thumb: If you are starting a new JVM service in 2026, Spring Boot is the default choice unless you have a compelling reason for a lighter stack.

2Starters and Auto-Configuration in Practice

Add one starter to your pom.xml or build.gradle and Boot pulls in a tested, compatible set of libraries:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

With spring-boot-starter-web on the classpath, auto-configuration registers:

  • An embedded Tomcat listening on port 8080
  • Jackson for JSON serialization
  • Spring MVC with sensible defaults

You override defaults through properties, not by rewriting config classes:

# application.properties
server.port=9090
spring.application.name=empforge-api

Boot's @ConditionalOnClass, @ConditionalOnMissingBean, and friends mean auto-config backs off when you define your own bean — your custom ObjectMapper wins over the default.

Inspect what Boot wired with --debug or the actuator/conditions endpoint (when Actuator is enabled).

3Building REST Controllers

Spring MVC maps HTTP requests to Java methods via annotations:

@RestController
@RequestMapping("/api/employees")
public class EmployeeController {

    private final EmployeeService employeeService;

    public EmployeeController(EmployeeService employeeService) {
        this.employeeService = employeeService;
    }

    @GetMapping
    public List<EmployeeDto> list() {
        return employeeService.findAll();
    }

    @GetMapping("/{id}")
    public EmployeeDto get(@PathVariable Long id) {
        return employeeService.findById(id);
    }

    @PostMapping
    @ResponseStatus(HttpStatus.CREATED)
    public EmployeeDto create(@RequestBody @Valid CreateEmployeeRequest req) {
        return employeeService.create(req);
    }
}

Key annotations:

  • @RestController — combines @Controller + @ResponseBody (return value becomes JSON)
  • @PathVariable — URI template variables (/employees/{id})
  • @RequestBody — deserialize JSON request body into a Java object

Rules of thumb:

  • Keep controllers thin — delegate business logic to services.
  • Return DTOs, not JPA entities, to control the JSON contract and avoid lazy-loading surprises.

4Dependency Injection: @Service, @Component, and @Autowired

Spring manages object lifecycles through an IoC container. You declare beans; Spring creates and wires them.

@Service
public class EmployeeService {
    private final EmployeeRepository repository;

    public EmployeeService(EmployeeRepository repository) {
        this.repository = repository;   // constructor injection — preferred
    }

    public EmployeeDto findById(Long id) {
        return repository.findById(id)
            .map(EmployeeDto::from)
            .orElseThrow(() -> new EmployeeNotFoundException(id));
    }
}

Constructor injection (shown above) is the modern default:

  • Dependencies are final — immutable and thread-safe
  • Required dependencies are obvious at a glance
  • Easy to unit-test without Spring context

@Autowired on fields works but hides dependencies and makes testing harder. If you must use field injection, prefer constructor injection instead.

Stereotype annotations register beans automatically:

  • @Component — generic bean
  • @Service — business logic layer
  • @Repository — data access layer
  • @RestController / @Controller — web layer

Ready to test yourself?

Sign in to take the quiz, track progress, and earn a certificate.

Sign in