Java + Spring Boot track

Lesson 23 · Part 6: Spring Boot

Getting Started with Spring Boot

Spring Boot is a framework that creates ready-to-run web applications without dozens of lines of XML with a “convention over configuration” philosophy. The server…

Part 6: Spring Boot3 min readFree lesson

Spring Boot is a framework that creates ready-to-run web applications without dozens of lines of XML with a “convention over configuration” philosophy. The server appears in one line, java -jar, including the built-in Tomcat.

Learning Objectives

  • Know the project structure provided by Spring Initializr
  • Know the role of @SpringBootApplication
  • Understand the concept of dependency injection (DI)
  • Change basic settings such as port and log with application.properties
  • Run as mvn spring-boot:run

Key concepts

1) Spring Initializr

If you access start.spring.io in your browser and select dependencies, a project zip will be created. We recommend the following options:

  • Project: Maven
  • Language: Java
  • Spring Boot: 3.3.x
  • Java: 21
  • Dependencies: Spring Web (+ 26 H2/JPA)

2) Standard project structure

spring-boot-app/
├── pom.xml
├── src/
│   ├── main/
│   │   ├── java/com/codingnow/lecture/spring23/Application.java
│   │   └── resources/application.properties
│   └── test/
│       └── java/com/codingnow/lecture/spring23/ApplicationTests.java

3) @SpringBootApplication

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

This one annotation is a meta annotation that combines 3 (@Configuration, @EnableAutoConfiguration, @ComponentScan). Automatically finds and registers beans in the same package/subpackage.

4) Illustration of Dependency Injection (DI)

@Service
class HelloService {
    String greet() { return "Hello, Spring!"; }
}

@RestController
class HelloController {
    private final HelloService service;
    HelloController(HelloService service) { this.service = service; }
    @GetMapping("/hello") String hello() { return service.greet(); }
}

Spring creates a HelloService object and automatically passes it to the controller constructor. The core of DI is a pattern that the caller does not directly new.

5) application.properties

server.port=8081
spring.application.name=lecture-spring23
logging.level.root=INFO

See as example

Example 1 — pom.xml : Spring Boot dependency

pom.xml (Summary):

<parent>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-parent</artifactId>
    <version>3.3.6</version>
</parent>

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

spring-boot-starter-web One dependency includes all built-in Tomcat, Jackson (JSON), and Spring MVC.

Example 2 — Application.java: Entry point

package com.codingnow.lecture.spring23;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}

Example 3 — HelloService.java + HelloController.java: First case of DI

HelloService.java :

package com.codingnow.lecture.spring23;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    public String greet(String name) {
        return "Hello, " + name + "!";
    }
}

HelloController.java :

package com.codingnow.lecture.spring23;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    private final HelloService service;

    public HelloController(HelloService service) {
        this.service = service;
    }

    @GetMapping("/hello")
    public String hello(@RequestParam(defaultValue = "Spring") String name) {
        return service.greet(name);
    }
}

Example 4 — application.properties

server.port=8081
spring.application.name=lecture-spring23

run

cd 06_Spring_Boot/23_Spring_Boot_Start
mvn spring-boot:run

In another terminal:

curl http://localhost:8081/hello
# Hello, Spring!

curl "http://localhost:8081/hello?name=Jisoo"
#Hello, Jisoo!

Common Mistakes

  1. Application.java cannot find components in other packages → Put them in the top package.
  2. Port conflict (8080 occupied) → change server.port
  3. Execution does not end with mvn spring-boot:run (exit with Ctrl+C)
  4. Use @Autowired field without constructor injection (difficult to test)
  5. Specify Spring Boot dependency versions one by one (managed by parent)

Cleanup

  • The pair @SpringBootApplication + main is the entry point
  • DI is a pattern of “not creating objects directly”
  • Environment settings with application.properties
  • Can be run immediately with mvn spring-boot:run

Try it yourself

cd 06_Spring_Boot/23_Spring_Boot_Start
mvn spring-boot:run
#another terminal
curl http://localhost:8081/hello

Example files

The runnable files used in this lesson. Copy them into your own project and experiment.

src/main/java/com/codingnow/lecture/spring23/Application.javaJava
package com.codingnow.lecture.spring23;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
src/main/java/com/codingnow/lecture/spring23/HelloController.javaJava
package com.codingnow.lecture.spring23;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {
    private final HelloService service;

    public HelloController(HelloService service) {
        this.service = service;
    }

    @GetMapping("/hello")
    public String hello(@RequestParam(defaultValue = "Spring") String name) {
        return service.greet(name);
    }
}
src/main/java/com/codingnow/lecture/spring23/HelloService.javaJava
package com.codingnow.lecture.spring23;

import org.springframework.stereotype.Service;

@Service
public class HelloService {
    public String greet(String name) {
        return "Hello, " + name + "!";
    }
}
src/main/resources/application.propertiesText
server.port=8081
spring.application.name=lecture-spring23
logging.level.root=INFO

Assignment

Problem — Ping endpoint + settings exposure

  • Reference solution: shown below
  • Core concepts: @RestController, @Value, application.properties

Requirements

  • Add a key called app.greeting=Hello to application.properties
  • GET /ping of PingController returns the following JSON:
    {"message": "hello", "status": "ok"}
    
  • Inject setting value into @Value("${app.greeting}")

Expected behavior

$ mvn spring-boot:run &
$ curl http://localhost:8082/ping
{"message":"hello","status":"ok"}

Check the correct answer

Check the Maven project in the reference solution below.

Show the reference solution

Try the assignment yourself first — comparing your attempt with a working solution is where most of the learning happens.

pom.xmlXML
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0">
    <modelVersion>4.0.0</modelVersion>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.3.6</version>
        <relativePath/>
    </parent>

    <groupId>com.codingnow</groupId>
    <artifactId>lecture-spring23-hw</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <java.version>21</java.version>
    </properties>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>
src/main/java/com/codingnow/lecture/spring23hw/Application.javaJava
package com.codingnow.lecture.spring23hw;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class Application {
    public static void main(String[] args) {
        SpringApplication.run(Application.class, args);
    }
}
src/main/java/com/codingnow/lecture/spring23hw/PingController.javaJava
package com.codingnow.lecture.spring23hw;

import java.util.Map;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class PingController {
    private final String greeting;

    public PingController(@Value("${app.greeting}") String greeting) {
        this.greeting = greeting;
    }

    @GetMapping("/ping")
    public Map<String, String> ping() {
        return Map.of("message", greeting, "status", "ok");
    }
}
src/main/resources/application.propertiesText
server.port=8082
spring.application.name=lecture-spring23-hw
app.greeting=Hello

Learn this lesson with a mentor

Work through the Java + Spring Boot track on your own, or join a guided cohort at our Pitampura campus and online.

Call NowEnroll Now