Skip to main content

๐Ÿง™ How Does Spring Boot Really Find Stuff?! (And How @SpringBootApplication + META-INF/spring.factories Do Their Secret Scan Magic)

 

๐Ÿ˜ต‍๐Ÿ’ซ When I started working in Spring Boot, I had a silly doubt… but it unlocked a serious concept.

I knew that @SpringBootApplication does a lot — it’s the entry point of every Spring Boot app.

So far, I only knew the basics:


@SpringBootApplication = @Configuration + @EnableAutoConfiguration + @ComponentScan

But one day I asked myself:

๐Ÿ’ญ “How does Spring Boot load classes from external libraries like spring-security, spring-web, or even a custom JAR I wrote and added in dependencies?
I never wrote any @ComponentScan for them… so how are their beans magically appearing inside my Spring Context?”

Yeah yeah… people say “Auto-configuration” or “Classpath scanning.” But how? Let’s deep dive ๐Ÿ”


๐Ÿšช Let’s First Talk About @ComponentScan

By default, this only scans packages below the class where @SpringBootApplication is placed.

So if your MainApp.java is in com.anand.app, it will scan:

com.anand.app.*

But will it scan classes inside:

org.springframework.security.config.annotation.*

๐Ÿค” Nope. Not unless Spring does something behind the scenes.


๐Ÿงณ Then How Are External JARs Loaded?

Let’s take Spring Web as an example.

You just add this:


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

๐Ÿ’ฅ Boom! You get a running server, a DispatcherServlet, Jackson for JSON, exception resolvers… like magic.

But where’s the magic wand?

That wand is called:


META-INF/spring.factories

๐Ÿ—‚️ What’s This spring.factories?

Inside each Spring Boot starter JAR, you’ll find:


META-INF/spring.factories

This file tells Spring Boot:

“Hey, I have some config classes to load. Even if the user didn’t scan me manually.”

Example from spring-boot-autoconfigure:


org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.security.servlet.SecurityAutoConfiguration,\ ...more...

This is how Spring Boot “auto-magically” adds beans — they’re listed here and picked up by @EnableAutoConfiguration.


๐Ÿงช So What Does @EnableAutoConfiguration Actually Do?

It does the heavy lifting. Here’s how:

  1. Scans the classpath for META-INF/spring.factories

  2. Loads all classes listed under EnableAutoConfiguration

  3. Instantiates them as configuration classes

  4. Each of them adds beans conditionally using annotations like:


@Bean @ConditionalOnClass(ObjectMapper.class)

So:

  • If Jackson is present → JSON config is loaded.

  • If not → config is skipped.

✨ It’s intelligent — it won’t load everything blindly.


๐Ÿ”„ Spring 2.7+ — What Changed?

Starting with Spring Boot 2.7+, this mechanism evolved for performance and modularity.

Now many starters use:


META-INF/spring/org.springframework.boot.autoconfigure.AutoConfiguration.imports

This is part of the newer @AutoConfiguration mechanism using AutoConfigurationImportSelector.

But the idea is the same — it loads stuff without requiring you to @ComponentScan them.


๐Ÿงช Real Example — How DispatcherServlet Comes In

Ever used a simple @RestController and hit it in browser?

You never configured a DispatcherServlet, right?

But this class is magically loaded from:


org.springframework.boot.autoconfigure.web.servlet.DispatcherServletAutoConfiguration

Which comes from:

spring.factories > EnableAutoConfiguration

Inside, it does:


@Bean public DispatcherServlet dispatcherServlet() { return new DispatcherServlet(); }

Spring Boot sees this during auto-config loading and registers it as a servlet.

๐ŸŽ‰ Boom. Your REST controller works.


๐Ÿคน Custom JARs Work the Same Way!

Want to create your own reusable Spring Boot library?

✅ Add your @Configuration class
✅ Put it in:


src/main/resources/META-INF/spring.factories

Like this:


org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ com.mycompany.autoconfig.MyCustomConfig

Now any project that adds your JAR will have this config loaded.


๐Ÿ’ฅ That’s Why Just Adding a Starter Works

Whether it’s:

  • spring-boot-starter-data-jpa

  • spring-boot-starter-security

  • resilience4j-spring-boot2

…they all use either:

  • spring.factories (older)

  • or AutoConfiguration.imports (newer)

No manual scanning. No XML. Just plugin and go.


๐Ÿ”š Wrapping Up

This small doubt I had while exploring Spring Boot opened up a whole world of internal magic — how Spring loads, scans, wires, and bootstraps everything without you even noticing.

Next time you wonder,

“How did that bean get in here?”

Remember: Spring invited it through a secret VIP list ๐ŸŽŸ️ in META-INF.


๐Ÿ’ฌ Did this help you clear some Spring mystery?

Tell me if you ever faced confusion like this — I’ll try to explain it with more examples .


Stay curious, stay caffeinated ☕ and keep debugging.

Anand ๐Ÿง‘‍๐Ÿ’ป

Comments

Popular posts from this blog

๐Ÿ” Is final Really Final in Java? The Truth May Surprise You ๐Ÿ˜ฒ

๐Ÿ’ฌ “When I was exploring what to do and what not to do in Java, one small keyword caught my eye — final . I thought it meant: locked, sealed, frozen — like my fridge when I forget to defrost it.”   But guess what? Java has its own meaning of final… and it’s not always what you expect! ๐Ÿ˜… Let’s break it down together — with code, questions, confusion, jokes, and everything in between. ๐ŸŽฏ The Confusing Case: You Said It's Final... Then It Changed?! ๐Ÿซ  final List<String> names = new ArrayList <>(); names.add( "Anand" ); names.add( "Rahul" ); System.out.println(names); // [Anand, Rahul] ๐Ÿคฏ Hold on... that’s final , right?! So how on earth is it still changing ? Time to dive deeper... ๐Ÿง  Why Is It Designed Like This? Here’s the key secret: In Java, final applies to the reference , not the object it points to . Let’s decode this like a spy mission ๐Ÿ•ต️‍♂️: Imagine This: final List<String> names = new ArrayList <>(); Be...

๐ŸŒŸ My Journey – From Zero to Senior Java Tech Lead ๐ŸŒŸ

 There’s one thing I truly believe… If I can become a Java developer, then anyone in the world can. ๐Ÿ’ฏ Sounds crazy? Let me take you back. ๐Ÿ•“ Back in 2015… I had zero coding knowledge . Not just that — I had no interest in coding either. But life has its own plans. In 2016, I got a chance to move to Bangalore and joined a Java course at a training center. That’s where it all started — Every day, every session made me feel like: "Ohhh! Even I can be a developer!" That course didn’t just teach Java — it gave me confidence . ๐Ÿงช Two Life-Changing Incidents 1️⃣ The Interview That Wasn't Planned Halfway through my course, I had to urgently travel to Chennai to donate blood to a family member. After that emotional rollercoaster, I found myself reflecting on my skills and the future. The next day, as I was preparing for my move to Bangalore to complete the remaining four months of my course, I randomly thought — "Let me test my skills... let me just see...

๐ŸŽข Java Loops: Fun, Fear, and ForEach() Fails

๐ŸŒ€ Oops, I Looped It Again! — The Ultimate Java Loop Guide You Won't Forget “I remember this question from one of my early interviews — I was just 2 years into Java and the interviewer asked, ‘Which loop do you prefer and why?’” At first, I thought, “Duh! for-each is cleaner.” But then he grilled me with cases where it fails. ๐Ÿ˜ต That led me to explore all loop types, their powers, and their pitfalls. Let’s deep-dive into every major Java loop with examples &  real-world guidance so you'll never forget again. ๐Ÿ” Loop Type #1: Classic For Loop — “The Old Reliable” ✅ When to Use: You need an index You want to iterate in reverse You want full control over loop mechanics ✅ Good Example: List<String> names = List.of("A", "B", "C"); for (int i = 0; i < names.size(); i++) { System.out.println(i + ": " + names.get(i)); } ๐Ÿ”ฅ Reverse + Removal Example: List<String> item...