Week 1: Spring Core

Demystifying Spring: A Beginner’s Journey into Spring Framework and Spring Boot (2 Part Series)

1 Demystifying Spring: A Beginner’s Journey into Spring Framework and Spring Boot
2 Week 1: Spring Core

Week 1: Demystifying the Spring Framework – Understanding the Core Concepts

Welcome to the first week of my journey into the Spring ecosystem! This article marks the beginning of my attempt to truly understand how Spring Framework works under the hood, particularly focusing on some of its most foundational concepts: IoC, Dependency Injection, Beans, and the ApplicationContext.



Before diving in, let’s first clarify a common confusion: Spring Framework vs.
Spring Boot.

Spring Framework vs. Spring Boot

Many newcomers (like myself) initially get confused between Spring Framework and Spring Boot, since they’re often used together. Here’s a simple breakdown:

Aspect Spring Framework Spring Boot
Purpose A comprehensive, modular Java framework for building enterprise apps A layer on top of Spring that simplifies setup and configuration
Configuraiton Requires manual setup of beans, XML or Java-based config Convention over configuration (sensible defaults, auto-config)
Starter Packs None Comes withe “starters” for web, JPA, security, etc.
Use Case When you need full control over the setup and structure When you want to get started quickly with minimal config
Built On Core Spring modules Core Spring modules (it’s not a replacement!)

So in essence, Spring Boot helps you build apps faster, but it’s still powered by Spring Framework underneath.

Here’s an illustration of how the dependency works:

What is Inversion of Control (IoC)?

IoC is the design principle at the heart of Spring. Normally in programming, you control how and when objects are created. But with IoC, you delegate that control to the framework.

Instead of writing code like this:

<span>Service</span> <span>myService</span> <span>=</span> <span>new</span> <span>Service</span><span>();</span>
<span>Service</span> <span>myService</span> <span>=</span> <span>new</span> <span>Service</span><span>();</span>
Service myService = new Service();

Enter fullscreen mode Exit fullscreen mode

Spring handles the object creation and injects it wherever it’s needed. This
inversion of control reduces tight coupling and increases flexibility. Thus, you
simply specify the dependency on your constructor and Spring will supply if for
you.

<span>public</span> <span>Controller</span><span>(</span><span>Service</span> <span>service</span><span>)</span> <span>{</span>
<span>this</span><span>.</span><span>service</span> <span>=</span> <span>service</span><span>;</span>
<span>}</span>
<span>public</span> <span>Controller</span><span>(</span><span>Service</span> <span>service</span><span>)</span> <span>{</span>
    <span>this</span><span>.</span><span>service</span> <span>=</span> <span>service</span><span>;</span>
<span>}</span>
public Controller(Service service) { this.service = service; }

Enter fullscreen mode Exit fullscreen mode

Dependency Injection (DI)

DI is a specific implementation of IoC where the framework injects the dependencies (i.e., other objects a class needs) automatically.

There are different types of DI:

  • Constructor Injection (recommended)
  • Setter Injection
  • Field Injection (less preferred)

Example Constructor Injection:

<span>@Component</span>
<span>public</span> <span>class</span> <span>UserService</span> <span>{</span>
<span>private</span> <span>final</span> <span>UserRepository</span> <span>userRepository</span><span>;</span>
<span>@Autowired</span>
<span>public</span> <span>UserService</span><span>(</span><span>UserRepository</span> <span>userRepository</span><span>)</span> <span>{</span>
<span>this</span><span>.</span><span>userRepository</span> <span>=</span> <span>userRepository</span><span>;</span>
<span>}</span>
<span>}</span>
<span>@Component</span>
<span>public</span> <span>class</span> <span>UserService</span> <span>{</span>
    <span>private</span> <span>final</span> <span>UserRepository</span> <span>userRepository</span><span>;</span>

    <span>@Autowired</span>
    <span>public</span> <span>UserService</span><span>(</span><span>UserRepository</span> <span>userRepository</span><span>)</span> <span>{</span>
        <span>this</span><span>.</span><span>userRepository</span> <span>=</span> <span>userRepository</span><span>;</span>
    <span>}</span>
<span>}</span>
@Component public class UserService { private final UserRepository userRepository; @Autowired public UserService(UserRepository userRepository) { this.userRepository = userRepository; } }

Enter fullscreen mode Exit fullscreen mode

Here, Spring automatically injects a UserRepository instance when creating UserService. However, this is no longer necessary if the target bean has only one constructor, full link here.

Example Setter Injection:

<span>public</span> <span>class</span> <span>SimpleMovieLister</span> <span>{</span>
<span>private</span> <span>MovieFinder</span> <span>movieFinder</span><span>;</span>
<span>@Autowired</span>
<span>public</span> <span>void</span> <span>setMovieFinder</span><span>(</span><span>MovieFinder</span> <span>movieFinder</span><span>)</span> <span>{</span>
<span>this</span><span>.</span><span>movieFinder</span> <span>=</span> <span>movieFinder</span><span>;</span>
<span>}</span>
<span>// ...</span>
<span>}</span>
<span>public</span> <span>class</span> <span>SimpleMovieLister</span> <span>{</span>
    <span>private</span> <span>MovieFinder</span> <span>movieFinder</span><span>;</span>

    <span>@Autowired</span>
    <span>public</span> <span>void</span> <span>setMovieFinder</span><span>(</span><span>MovieFinder</span> <span>movieFinder</span><span>)</span> <span>{</span>
        <span>this</span><span>.</span><span>movieFinder</span> <span>=</span> <span>movieFinder</span><span>;</span>
    <span>}</span>

    <span>// ...</span>
<span>}</span>
public class SimpleMovieLister { private MovieFinder movieFinder; @Autowired public void setMovieFinder(MovieFinder movieFinder) { this.movieFinder = movieFinder; } // ... }

Enter fullscreen mode Exit fullscreen mode

Example Field Injection:

<span>public</span> <span>class</span> <span>MovieRecommender</span> <span>{</span>
<span>private</span> <span>final</span> <span>CustomerPreferenceDao</span> <span>customerPreferenceDao</span><span>;</span>
<span>@Autowired</span>
<span>private</span> <span>MovieCatalog</span> <span>movieCatalog</span><span>;</span>
<span>@Autowired</span>
<span>public</span> <span>MovieRecommender</span><span>(</span><span>CustomerPreferenceDao</span> <span>customerPreferenceDao</span><span>)</span> <span>{</span>
<span>this</span><span>.</span><span>customerPreferenceDao</span> <span>=</span> <span>customerPreferenceDao</span><span>;</span>
<span>}</span>
<span>// ...</span>
<span>}</span>
<span>public</span> <span>class</span> <span>MovieRecommender</span> <span>{</span>

    <span>private</span> <span>final</span> <span>CustomerPreferenceDao</span> <span>customerPreferenceDao</span><span>;</span>

    <span>@Autowired</span>
    <span>private</span> <span>MovieCatalog</span> <span>movieCatalog</span><span>;</span>

    <span>@Autowired</span>
    <span>public</span> <span>MovieRecommender</span><span>(</span><span>CustomerPreferenceDao</span> <span>customerPreferenceDao</span><span>)</span> <span>{</span>
        <span>this</span><span>.</span><span>customerPreferenceDao</span> <span>=</span> <span>customerPreferenceDao</span><span>;</span>
    <span>}</span>

    <span>// ...</span>
<span>}</span>
public class MovieRecommender { private final CustomerPreferenceDao customerPreferenceDao; @Autowired private MovieCatalog movieCatalog; @Autowired public MovieRecommender(CustomerPreferenceDao customerPreferenceDao) { this.customerPreferenceDao = customerPreferenceDao; } // ... }

Enter fullscreen mode Exit fullscreen mode

🫘 What are Beans?

A Bean is simply an object that is managed by the Spring container. You define a bean by annotating a class with @Component, @Service,
@Repository, or by using @Bean in a configuration class.

<span>@Component</span>
<span>public</span> <span>class</span> <span>EmailService</span> <span>{</span>
<span>public</span> <span>void</span> <span>sendEmail</span><span>(</span><span>String</span> <span>to</span><span>,</span> <span>String</span> <span>message</span><span>)</span> <span>{</span>
<span>// send email</span>
<span>}</span>
<span>}</span>
<span>@Component</span>
<span>public</span> <span>class</span> <span>EmailService</span> <span>{</span>
    <span>public</span> <span>void</span> <span>sendEmail</span><span>(</span><span>String</span> <span>to</span><span>,</span> <span>String</span> <span>message</span><span>)</span> <span>{</span>
        <span>// send email</span>
    <span>}</span>
<span>}</span>
@Component public class EmailService { public void sendEmail(String to, String message) { // send email } }

Enter fullscreen mode Exit fullscreen mode

This class becomes a Spring-managed bean, meaning Spring takes care of its lifecycle and dependencies.

️ ApplicationContext: The Spring Container

The ApplicationContext is the core interface of the Spring container. It holds all the beans and manages their life cycles.

Think of it as a registry that:

  • Creates and wires beans
  • Manages their scopes
  • Provides internationalization
  • Handles event propagation

When you create a Spring Boot app, ApplicationContext is automatically initialized for you. In traditional Spring, you might initialize it manually like this:

<span>ApplicationContext</span> <span>context</span> <span>=</span> <span>new</span> <span>AnnotationConfigApplicationContext</span><span>(</span><span>AppConfig</span><span>.</span><span>class</span><span>);</span>
<span>MyService</span> <span>service</span> <span>=</span> <span>context</span><span>.</span><span>getBean</span><span>(</span><span>MyService</span><span>.</span><span>class</span><span>);</span>
<span>ApplicationContext</span> <span>context</span> <span>=</span> <span>new</span> <span>AnnotationConfigApplicationContext</span><span>(</span><span>AppConfig</span><span>.</span><span>class</span><span>);</span>
<span>MyService</span> <span>service</span> <span>=</span> <span>context</span><span>.</span><span>getBean</span><span>(</span><span>MyService</span><span>.</span><span>class</span><span>);</span>
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class); MyService service = context.getBean(MyService.class);

Enter fullscreen mode Exit fullscreen mode

Final Thoughts

Understanding IoC, DI, Beans, and the ApplicationContext helps demystify a large part of Spring. These concepts might seem abstract at first, but they are the foundation that powers the rest of the framework—and every feature you’ll use in Spring Boot.

⏭️ Up Next: Week 2 – Spring Boot Basics

Next week, we’ll explore how Spring Boot simplifies setup using auto-configuration, starter dependencies, and devtools. I’ll walk through building your first Spring Boot app from scratch.

If you have any feedback, corrections, or ideas, feel free to share them. See you in the next one!

Demystifying Spring: A Beginner’s Journey into Spring Framework and Spring Boot (2 Part Series)

1 Demystifying Spring: A Beginner’s Journey into Spring Framework and Spring Boot
2 Week 1: Spring Core

原文链接:Week 1: Spring Core

© 版权声明
THE END
喜欢就支持一下吧
点赞11 分享
Those who fly solo have the strongest wings.
那些单独飞翔的人拥有最强大的翅膀
评论 抢沙发

请登录后发表评论

    暂无评论内容