Tutorials Logic, IN info@tutorialslogic.com

Start Spring Setup Environment Create First Application

Boot Application Startup

Spring Boot assembles a Spring application from your code, selected dependencies, configuration, and auto-configuration. This lesson targets Spring Boot 4.1, which requires Java 17 or later. You will generate a small project, understand what the application class activates, run one HTTP endpoint, and verify both the success and failure paths.

The goal is not to memorize generated folders. It is to understand the startup chain: the JVM runs main(), SpringApplication creates the application context, component scanning discovers your classes, auto-configuration contributes infrastructure based on the classpath, and the embedded server begins accepting requests.

Project Generation

Spring Initializr creates a build that matches the Spring Boot version and dependencies you select. Choose Java, a supported build tool, Java 17 or newer, and only the starters required for the first capability. For an MVC JSON endpoint, Spring Web is enough; add validation, persistence, security, or observability when the application actually needs them.

A starter is a curated dependency entry point, not a framework feature by itself. The build tool resolves its transitive libraries. Keep the generated wrapper files so every developer and CI job can use the project-approved build-tool version without relying on a machine-wide installation.

  • Use a reverse-domain group name and a stable artifact name.
  • Keep the main application class in a root package above controllers and services.
  • Do not add every starter preemptively; unnecessary dependencies widen startup and security surface.
  • Commit wrapper scripts and wrapper configuration with the project.

Maven pom.xml - Spring Boot Starter

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

    <!-- Spring Boot Parent: manages all dependency versions -->
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>3.2.0</version>
    </parent>

    <groupId>com.example</groupId>
    <artifactId>my-spring-app</artifactId>
    <version>1.0.0</version>
    <packaging>jar</packaging>

    <properties>
        <java.version>17</java.version>
    </properties>

    <dependencies>
        <!-- Web MVC + embedded Tomcat -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>

        <!-- JPA + Hibernate -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>

        <!-- MySQL Driver -->
        <dependency>
            <groupId>com.mysql</groupId>
            <artifactId>mysql-connector-j</artifactId>
            <scope>runtime</scope>
        </dependency>

        <!-- Spring Security -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-security</artifactId>
        </dependency>

        <!-- Thymeleaf template engine -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-thymeleaf</artifactId>
        </dependency>

        <!-- Actuator: health, metrics, info endpoints -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>

        <!-- Testing -->
        <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>

Configuration Sources

application.properties or application.yaml supplies defaults, while environment variables and command-line arguments can override deployment-specific values. Keep secrets outside version-controlled files. Group related custom values with typed configuration properties instead of scattering @Value expressions across the codebase.

Profiles can select environment-specific beans or configuration, but they should not turn one application into several unrelated products. A production artifact should be built once and configured at runtime. Log the active profiles and sanitized configuration decisions so deployment mistakes are diagnosable without exposing credentials.

application.properties Configuration

application.properties Configuration
# Server configuration
server.port=8080
server.servlet.context-path=/api

# Database configuration
spring.datasource.url=jdbc:mysql://localhost:3306/mydb?useSSL=false
spring.datasource.username=root
spring.datasource.password=password
spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver

# JPA/Hibernate
spring.jpa.hibernate.ddl-auto=update
spring.jpa.show-sql=true
spring.jpa.properties.hibernate.format_sql=true
spring.jpa.database-platform=org.hibernate.dialect.MySQL8Dialect

# Logging
logging.level.org.springframework=INFO
logging.level.com.example=DEBUG
logging.file.name=logs/app.log

# Actuator
management.endpoints.web.exposure.include=health,info,metrics
management.endpoint.health.show-details=always

# Custom properties
app.name=My Spring App
app.version=1.0.0
app.jwt.secret=mySecretKey123

application.properties

application.properties
# application.yml (YAML format - same config, different syntax)
server:
  port: 8080
  servlet:
    context-path: /api

spring:
  datasource:
    url: jdbc:mysql://localhost:3306/mydb?useSSL=false
    username: root
    password: password
  jpa:
    hibernate:
      ddl-auto: update
    show-sql: true

logging:
  level:
    org.springframework: INFO
    com.example: DEBUG

app:
  name: My Spring App
  version: 1.0.0

Application Class

@SpringBootApplication combines configuration, auto-configuration, and component scanning. SpringApplication.run() creates and refreshes the context, then returns it. Place this class high enough in the package hierarchy for scanning to find your components; otherwise a controller can compile correctly yet never become a bean.

Auto-configuration is conditional. It reacts to classes, beans, and properties that are present, and backs away when you supply your own bean. When startup fails, read the first meaningful cause and the condition evaluation information instead of adding annotations at random.

Hello World REST Controller

Hello World REST Controller
package com.example.controller;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;

@RestController
@RequestMapping("/api")
public class HelloController {

    @Value("${app.name}")
    private String appName;

    @GetMapping("/hello")
    public String hello() {
        return "Hello from " + appName + "!";
    }

    @GetMapping("/hello/{name}")
    public String helloName(@PathVariable String name) {
        return "Hello, " + name + "!";
    }

    @GetMapping("/greet")
    public String greet(@RequestParam(defaultValue = "World") String name) {
        return "Greetings, " + name + "!";
    }
}

First Spring Boot Application

First Spring Boot Application
package com.example;

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);
        // App starts at http://localhost:8080
        // Test: curl http://localhost:8080/api/hello
        // Test: curl http://localhost:8080/api/hello/Alice
        // Test: curl http://localhost:8080/api/greet?name=Bob
    }
}

First Endpoint

A small endpoint proves that scanning, MVC configuration, JSON conversion, and the embedded server all work. Keep the controller thin: bind and validate transport input, call a service, and convert the result into the intended HTTP response. Business rules should remain testable without starting a server.

Health Message Endpoint

Health Message Endpoint
package com.example.demo.web;

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

@RestController
class StatusController {
    record Status(String state, String message) {}

    @GetMapping("/api/status")
    Status status() {
        return new Status("ready", "Application context started");
    }
}
Output
{"state":"ready","message":"Application context started"}

Spring MVC maps GET /api/status to status(). The returned record is written as JSON by an HTTP message converter available through the web starter.

Run and Diagnose

Run through the project wrapper, then call the endpoint from a browser or HTTP client. A clean startup log should show the application name, active profiles, server port, and completion time. Stop the process cleanly so lifecycle callbacks and resource pools can close.

If the port is occupied, choose another server.port rather than terminating an unknown process. If the endpoint returns 404, confirm the request path and package scanning. If startup reports an unsatisfied dependency, identify the missing bean and constructor path. If the JVM version is unsupported, fix the toolchain before changing application code.

  • Verify java -version before investigating framework errors.
  • Use the generated wrapper for repeatable local and CI builds.
  • Test one expected response and one not-found or validation path.
  • Keep production secrets in an approved external configuration source.
Before you move on

Startup Verification

5 checks
  • Use Java 17 or newer for Spring Boot 4.1.
  • Generate only the starters needed by the current capability.
  • Place the application class above components in the package hierarchy.
  • Keep environment values external and secrets out of committed properties.
  • Call the first endpoint and diagnose errors from their earliest useful cause.

Startup Problems

  • Controller is outside component scan

    Move it under the application package or configure scanning intentionally.
  • Machine build differs from CI

    Use and commit the generated Gradle or Maven wrapper.
  • Secret committed in properties

    Read it from an approved environment or secret store and rotate the exposed value.

Try this next

Prove the Startup Chain

0 of 3 completed

  1. Select Spring Web only, run it with the wrapper, and record the startup sequence.
  2. Change the server port through an environment or command-line value without editing the packaged application.
  3. Move the controller outside the root package, observe 404, then restore the correct package structure.

Boot Setup Questions

No. The official system requirements specify Java 17 as the minimum, although newer supported JDKs can be used.

No, but it provides a reliable project baseline with compatible plugin and dependency management.

A common cause is that the controller is outside component scanning or the requested mapping differs from the declared path.

Browse Free Tutorials

Explore 500+ free tutorials across 20+ languages and frameworks.