πŸš€ Getting Started with Spring Boot: My Journey from Confusion πŸ˜΅β€πŸ’« to REST API Creation πŸ”§πŸŒ

When I first started learning Spring Boot, I didn’t expect it to be this intense. Coming from a different tech stack, wrapping my head around all the annotations, beans, and configurations was... a lot. πŸ˜΅β€πŸ’«

Lets first understand the basics differences between Spring and SpringBoot

Spring vs spring boot

BasisSpringSpring Boot
Where it’s used?Spring framework is a java EE framework that is used to build applications.Spring Boot framework is mainly used to develop REST API’s
Key featureThe primary or most important feature of the Spring framework is dependency injection(Dependency Injection (DI) is a design technique that removes dependencies from computer code, making the application easier to maintain and test).The main or primary feature of the Spring Boot is Autoconfiguration( Simply described, Spring Boot autoconfiguration is a method of automatically configuring a Spring application based on the dependencies found on the classpath.)

Autoconfiguration can speed up and simplify development by removing the need to define some beans that are part of the auto-configuration classes. | | Why it’s used | Its goal is to make Java EE (Enterprise Edition) development easier, allowing developers to be more productive. | Spring Boot provides the RAD(Rapid Application Development) feature to the Spring framework for faster application development. | | Type of Application Development | Spring framework helps to create a loosely coupled application. | Spring Boot helps to create a stand-alone application. | | Servers dependency | In the Spring framework to test the Spring Project, we need to set up the servers explicitly. | Spring Boot offers built-in or embedded servers such as Tomcat and jetty. | | In-memory database support | Spring framework does not provide support for the in-memory database. | Spring Boot provides support for the in-memory database such as H2. | | Dependencies | Spring Framework requires a number of dependencies to create a web app. | Spring Boot, on the other hand, can get an application working with just one dependency. There are several more dependencies required during build time that is added to the final archive by default. | | Testing | Testing in Spring Boot is difficult in comparison to Spring Boot due to a large amount of source code. | Testing in Spring Boot is easier due to the reduced amount of source code. | | Plugins | Spring framework does not provide any plugin for maven, Gradle, etc. like Spring Boot. | Spring Boot provides build tool plugins for Maven and Gradle. The Plugins offer a variety of features, including the packaging of executable jars. |

🌰 What is a Bean in Spring?

In Spring, a Bean is simply an object that is managed by the Spring container.

Think of it like this:

You write the class, and Spring takes care of creating the object, storing it, and injecting it wherever needed. That object is now a β€œSpring Bean.”

πŸ—οΈ How Are Beans Created?

There are three main ways to create Beans in Spring:

1. Using Annotations (@Component, @Service, @Repository, @Controller)

Spring automatically picks up these annotations during component scanning and registers them as Beans.

2. Using @Bean in a Configuration Class

You can manually define a bean inside a class annotated with @Configuration.

3. Through External Libraries (e.g., Spring Data JPA, Spring Security)

Sometimes you don’t even write the class yourself β€” Spring Boot auto-configures and injects beans from libraries (like the DataSource, EntityManager, etc.) using auto-configuration.

Why Use Beans?

  • You avoid manually instantiating objects with new

  • Spring controls the lifecycle and reuses beans (singleton by default)

  • It makes Dependency Injection possible (which you can explain right after this!)

🧬 What is Dependency Injection in Spring Boot?

Dependency Injection (DI) is a design pattern where an object receives its dependencies β€” rather than creating them itself. This is one of the core principles of Spring, and it’s what makes your code modular, testable, and easier to manage.

Let’s say your class needs an object (like a Service or Repository) to work. Instead of writing:

UserService userService = new UserService();

Spring Boot does the heavy lifting for you and injects the required object automatically. This avoids:

  • Tight coupling

  • Manual object creation

  • Difficulty testing with mocks

πŸ”§ Types of Dependency Injection in Spring

  1. Constructor Injection βœ…

  2. Field Injection

  3. Setter Injection

Let’s focus on Constructor Injection, the most widely recommended approach.

βœ… Real Example: Constructor Injection

1. Create a Bean (Engine)



@Component
public class Engine {
    public void start() {
        System.out.println("Engine started!");
    }
}

2. Inject the Bean (Car)

@Component
public class Car {
    private final Engine engine;

    @Autowired
    public Car(Engine engine) {
        this.engine = engine;
    }

    public void drive() {
        engine.start();
        System.out.println("Car is driving...");
    }
}

3. Run the App

@SpringBootApplication
public class myapp implements CommandLineRunner {

    @Autowired
    private Car car;

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

    @Override
    public void run(String... args) throws Exception {
        car.drive();
    }
}

✨ What is Auto-Configuration in Spring Boot?

One of the most powerful and magical features of Spring Boot is Auto-Configuration. It’s what allows you to build working apps quickly without writing tons of boilerplate configuration code.

But what does it really mean?

πŸ€– What Does Auto-Configuration Do?

Spring Boot looks at:

  • The dependencies in your classpath (like Spring Web, Spring Data JPA, etc.)

  • Your application properties

  • The context of your app

And then it automatically configures beans, services, and settings β€” without you having to write XML or Java config manually.

πŸ” Who Triggers Auto-Configuration?

@SpringBootApplication

Which is actually a shortcut for:

@Configuration
@EnableAutoConfiguration
@ComponentScan

βš™οΈ What Really Happens Under the Hood with Auto-Configuration?

πŸ” Step-by-Step Behind the Scenes

1. @EnableAutoConfiguration kicks off everything

When your app starts, Spring sees:

@SpringBootApplication // this includes @EnableAutoConfiguration

This tells Spring:

β€œTry to automatically configure beans based on what’s in the classpath and my config files.”

This is handled by the EnableAutoConfigurationImportSelector β€” a class that tells Spring which auto-configurations to apply.

2. Spring loads a list of potential configuration classes

This list is found inside:

META-INF/spring.factories

3. Conditional Configuration is Checked

Each auto-config class uses conditional annotations to decide whether to activate.

@ConditionalOnClass(DataSource.class)
@ConditionalOnProperty(name = "spring.datasource.url")
public class AutoConfiguration {

}

This means:

βœ… THEN Spring auto-configures a DataSource bean for you.

  1. Auto-configured Beans Are Injected Like Any Other

Once Spring decides to apply an auto-config class, it registers the beans inside it β€” and you can @Autowired or use constructor injection as usual.

Auto-Config Life Cycle:

  1. @EnableAutoConfiguration triggers it

  2. Spring loads candidate config classes from spring.factories

  3. Each class checks conditions via annotations like @ConditionalOnClass

  4. Matching configs create beans

  5. You can override any of them with your own beans

Here's a look at how and where auto-configuration files are structured.

Okay, now that we've covered the basics of Spring Boot, let's dive into how REST APIs work and how real-world requests are handled.

🌐Building REST APIs in Spring Boot

Spring Boot makes it super easy to build REST APIs. A typical project follows a layered architecture that helps keep things clean, modular, and scalable.

Let’s break it down using an example: a User Management API (GET, POST, DELETE users).

πŸ“ Typical Project Structure

com.example.myapp
β”‚
β”œβ”€β”€ controller      --> Handles HTTP requests
β”œβ”€β”€ service         --> Business logic
β”œβ”€β”€ dto             --> Data Transfer Objects
β”œβ”€β”€ entity          --> JPA entities (database models)
β”œβ”€β”€ repository      --> Interfaces for DB access

πŸ”Έ 1. Entity Layer β€” User

// entity/User.java
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    private String name;
    private String email;

    // getters and setters
}

πŸ”Έ 2. DTO Layer β€” UserDTO

// dto/UserDTO.java
public class UserDTO {

    private String name;
    private String email;

    // getters and setters
}

🧠 DTOs are used to expose only the necessary data through APIs, hiding sensitive/internal fields like passwords or IDs.

πŸ”Έ 3. Repository Layer β€” UserRepository

// repository/UserRepository.java
@Repository
public interface UserRepository extends JpaRepository<User, Long> {
}

🧠 Spring Boot auto-generates all CRUD methods β€” thanks to JpaRepository.
Please explore the power of JPA Repository. It's amazing because you don't have to configure or write methods to handle SQL for database communication. JPA Repository does it for us and also provides custom methods for interacting with the database.

4. Service Layer β€” UserService

// service/UserService.java
@Service
public class UserService {

    @Autowired
    private UserRepository userRepository;

    public List<User> getAllUsers() {
        return userRepository.findAll();
    }

    public User saveUser(User user) {
        return userRepository.save(user);
    }

    public void deleteUser(Long id) {
        userRepository.deleteById(id);
    }
}

🧠 This is where your business logic lives.

πŸ”Έ 5. Controller Layer β€” UserController

// controller/UserController.java
@RestController
@RequestMapping("/api/users")
public class UserController {

    @Autowired
    private UserService userService;

    @GetMapping
    public List<User> getUsers() {
        return userService.getAllUsers();
    }

    @PostMapping
    public User createUser(@RequestBody User user) {
        return userService.saveUser(user);
    }

    @DeleteMapping("/{id}")
    public void deleteUser(@PathVariable Long id) {
        userService.deleteUser(id);
    }
}

πŸ“ Article Summary β€” β€œMy Journey into Spring Boot & REST APIs”

In this article, I shared my hands-on journey of building RESTful APIs using Spring Boot β€” starting from confusion and slowly connecting the dots between concepts like Beans, Dependency Injection, and Auto-Configuration.

βœ… What I Covered:

  • Spring Boot Project Setup
    Using Spring Initializr and managing dependencies with Maven/Gradle.

  • Understanding Beans
    What beans are, how Spring creates them (@Component, @Bean), and why Spring needs to manage them for features like Dependency Injection.

  • Dependency Injection
    Explained with code β€” how Spring automatically injects required dependencies, and why it makes your code more modular and testable.

  • Auto-Configuration
    The β€œmagic” behind Spring Boot that configures beans based on classpath + properties. Went deep into how @EnableAutoConfiguration works and how Spring decides what to auto-configure using spring.factories.

  • Project Structure for REST APIs
    Shared a clean, real-world folder structure using controller, service, dto, entity, and repository packages β€” with code examples for a simple User API.

    "Alrighty, see you in the next one! And hey β€” don’t forget to smash that like button!" πŸ˜„πŸ‘

0
Subscribe to my newsletter

Read articles from shrivatsa chitgopkar directly inside your inbox. Subscribe to the newsletter, and don't miss out.

Written by

shrivatsa chitgopkar
shrivatsa chitgopkar