Wednesday, 16 April 2025

๐Ÿ”ฎ Understanding Future in Java (With Simple Example)

 In Java, working with multithreading and asynchronous programming is made much easier with the help of the java.util.concurrent package. One of the key components in this package is the Future interface.

If you’ve ever needed to run a task in the background and retrieve the result once it's done — without blocking your entire program — then Future is your friend.


๐Ÿš€ What is Future?

A Future represents the result of an asynchronous computation. It acts like a placeholder for a value that will eventually be available after a long-running task completes.

In simple terms, when you submit a task to a thread pool (using an ExecutorService), instead of immediately getting the result, you get a Future object that promises to hold the result once the task finishes.


๐Ÿงต Why Use Future?

  • Perform background operations without blocking the main thread.

  • Check if a task is done with .isDone().

  • Cancel a running task with .cancel(true).

  • Get the result later using .get() (blocks if the result isn't ready).


๐Ÿง‘‍๐Ÿ’ป Basic Example: Using Future with Callable

Here’s a beginner-friendly example showing how to use Future in Java:


import java.util.concurrent.*; public class FutureExample { public static void main(String[] args) throws Exception { // Step 1: Create a thread pool (ExecutorService) ExecutorService executor =
Executors.newSingleThreadExecutor(); // Step 2: Submit a Callable task to the executor Future<Integer> future = executor.submit(new Callable<Integer>() { @Override public Integer call() throws Exception { // Simulate long-running task (e.g., network call, calculation) Thread.sleep(2000); // 2 seconds delay return 10 + 20; } }); System.out.println("Task submitted... Doing other work while waiting"); // Step 3: Do something else while the task runs // Step 4: Get the result (this will block if the task is not finished) Integer result = future.get(); // Step 5: Print the result System.out.println("Result from background task: " + result); // Step 6: Shutdown the executor executor.shutdown(); } }

๐Ÿ–จ️ Output:


Task submitted... Doing other work while waiting Result from background task: 30

๐Ÿ” Explanation:

ExecutorService executor = Executors.newSingleThreadExecutor();

Creates a thread pool with a single thread that will run the submitted tasks.

Future<Integer> future = executor.submit(...)

Submits a Callable task (which returns a value), and returns a Future object.

future.get();

Waits for the task to complete and returns the result. If the task isn’t done yet, it blocks the current thread until it is.

executor.shutdown();

Always shut down the executor to avoid memory leaks or keeping the app running unnecessarily.


๐Ÿ“Œ Additional Tips

  • future.isDone() → returns true if the task is completed.

  • future.cancel(true) → cancels the task if it's not finished yet.

  • Callable<V> vs Runnable: use Callable if you need to return a value or throw exceptions.


๐Ÿค” When Should You Use Future?

Use Future when you:

  • Need to perform background tasks (like file I/O or API calls).

  • Want to run multiple tasks in parallel and wait for results.

  • Want the ability to cancel a task if it’s taking too long.


๐Ÿ’ก Bonus: Want More Power? Try CompletableFuture

If you’re looking for even more flexibility (like chaining tasks, handling errors, async pipelines), check out CompletableFuture. It’s the modern alternative introduced in Java 8.

Monday, 7 April 2025

๐ŸŽฏ Tricky Java 8 map() vs flatMap() Questions

๐Ÿ”ฅ Q1: What's the output of this?


List<String> words = Arrays.asList("Java", "Spring"); List<String> result = words.stream() .map(word -> word.split("")) .flatMap(Arrays::stream) .distinct() .collect(Collectors.toList()); System.out.println(result);

Answer:

Output:


[J, a, v, S, p, r, i, n, g]
  • word.split("") → gives String[]

  • map() gives Stream<String[]>

  • flatMap(Arrays::stream) flattens Stream<String[]>Stream<String>

  • distinct() removes duplicates

๐Ÿ”ฅ Trick: map(Arrays::stream) would give you Stream<Stream<String>> and fail to compile in .collect().



๐Ÿ”ฅ Q2: Why does this not compile?


List<List<Integer>> list = Arrays.asList( Arrays.asList(1, 2), Arrays.asList(3, 4) ); List<Stream<Integer>> result = list.stream() .map(l -> l.stream()) .collect(Collectors.toList());

Answer:

It compiles, but the result is List<Stream<Integer>>, not List<Integer>.

To flatten the list, use:


List<Integer> result = list.stream() .flatMap(List::stream) .collect(Collectors.toList());

๐Ÿ‘‰ Trick: flatMap is needed to flatten nested streams.


๐Ÿ”ฅ Q3: How is flatMap() different from map() in Optional?


Optional<String> name = Optional.of("Java"); Optional<Optional<String>> result = name.map(n -> Optional.of(n.toUpperCase())); Optional<String> flat = name.flatMap(n -> Optional.of(n.toUpperCase()));

Answer:

  • map() → wraps result → Optional<Optional<String>>

  • flatMap() → avoids wrapping → Optional<String>

๐Ÿง  Trick: Use flatMap when the function already returns an Optional.


๐Ÿ”ฅ Q4: What happens here?


Stream<String> stream = Stream.of("apple", "banana"); stream.map(s -> s.toUpperCase()); stream.forEach(System.out::println);

Answer:

๐Ÿ’ฅ Runtime Exception: IllegalStateException: stream has already been operated upon or closed

Why? Because map() doesn’t mutate the original stream — it returns a new one. But it was never assigned.

๐Ÿง  Trick: Streams are one-time use. Always assign or chain after map() or flatMap().


๐Ÿ”ฅ Q5: Can you convert a List<String> where each string is comma-separated into a List<String> of all elements?

Answer:

Yes, with flatMap():


List<String> input = Arrays.asList("a,b,c", "d,e"); List<String> result = input.stream() .map(s -> s.split(",")) .flatMap(Arrays::stream) .collect(Collectors.toList());

Output:


[a, b, c, d, e]

๐Ÿ’ก Trick: split() gives arrays. Need flatMap(Arrays::stream) to flatten.


๐Ÿ”ฅ Q6: What’s the output?


List<String> list = Arrays.asList("a,b", "c,d", "e"); List<String[]> mapped = list.stream() .map(s -> s.split(",")) .collect(Collectors.toList()); System.out.println(mapped.size()); // ? System.out.println(mapped.get(0)[0]); // ?

Answer:

  • mapped.size() → 3

  • mapped.get(0)[0]"a"

๐Ÿง  Trick: map() does not flatten — you still have a List<String[]>, not a flat List<String>. Only flatMap() can do that.


๐Ÿ”ฅ Q7: What does this do?


Stream<String> stream = Stream.of("java", "spring"); Stream<Stream<Character>> result = stream.map(str -> str.chars().mapToObj(c -> (char) c) );

Answer:

  • It creates a Stream<Stream<Character>>

  • Each inner stream represents characters of a string

✅ If you want a flat Stream<Character>:


Stream<Character> flat = stream .flatMap(str -> str.chars().mapToObj(c -> (char) c));

๐Ÿ”ฅ Trick: Interviewers love chars + streams + mapping → always pay attention to return types.


๐Ÿ”ฅ Q8: Can you use flatMap() with primitives?

Answer:

Yes, but carefully! Primitives like IntStream, LongStream etc. don't work directly with flatMap.

Example:


List<String> list = Arrays.asList("1,2", "3,4"); List<Integer> result = list.stream() .map(s -> s.split(",")) .flatMap(Arrays::stream) .map(Integer::parseInt) .collect(Collectors.toList());

๐Ÿ”ฅ Trick: To flatMap a primitive stream, use:


.flatMapToInt(str -> str.chars()) // returns IntStream

๐Ÿ”ฅ Q9: Which is more efficient: map().flatMap() vs flatMap() directly?

Answer:

  • If you're nesting transformations (e.g. map().map()), it's fine.

  • But if you're mapping and flattening, flatMap() is better.

Bad:


.stream() .map(x -> someMethodReturningStream(x)) .map(stream -> stream.collect(Collectors.toList())) // Oops!

Better:


.stream() .flatMap(this::someMethodReturningStream)

๐Ÿ”ฅ Trick: .flatMap() avoids intermediate structures (like List of Lists) — better for performance and memory.


๐Ÿ”ฅ Q10: What if flatMap returns null?


Stream.of("hello", "world") .flatMap(s -> null) // What happens here? .collect(Collectors.toList());

Answer:

๐Ÿ’ฅ NullPointerException

❌ You cannot return null from a flatMap — it must return a valid Stream. If you want an empty result, return Stream.empty().

Correct way:


.flatMap(s -> Stream.empty())

๐Ÿ”ฅ Trick: Always return a Stream, even if it’s empty. No null allowed in flatMap().


๐Ÿงช Final Trick:

"Use map() when you transform values. Use flatMap() when you're dealing with nested structures (like lists of lists or Optionals of Optionals)."

Saturday, 5 April 2025

 

๐ŸŽฏ 10 Tricky Spring Boot Bean Creation Interview Questions (With Answers)

Knowing how Spring Boot manages beans is critical for backend interviews. Here's a curated list of tricky but real-world interview questions, each with a sharp, confident answer you can use in your blog or interviews.


✅ 1. How many instances of a @Component bean are created by default in Spring Boot?

✔️ Answer:

Only one instance is created per Spring container. This is due to the default singleton scope in Spring.

Bonus: You can verify this by comparing two injected references or printing the bean hashcode.


✅ 2. How do you create a new object of a bean every time it's needed?

✔️ Answer:

Use the @Scope("prototype") annotation:


@Component @Scope("prototype") public class MyService { ... }

Now Spring will create a new instance every time the bean is requested.


✅ 3. Can you use @Autowired with prototype-scoped beans?

✔️ Answer:

Yes, but be careful!

  • If injected directly via @Autowired, Spring injects only once (at startup).

  • To get a new object every time, use ObjectFactory or Provider:


@Autowired private ObjectFactory<MyPrototypeBean> factory; factory.getObject(); // gives new instance each time

✅ 4. How does Spring Boot know which beans to create?

✔️ Answer:

Spring Boot uses @ComponentScan (inside @SpringBootApplication) to automatically detect classes annotated with:

  • @Component

  • @Service

  • @Repository

  • @Controller


✅ 5. How to find out how many beans Spring has created at startup?

✔️ Answer:

In your main class:


ApplicationContext ctx = SpringApplication.run(MyApp.class, args); System.out.println("Bean count: " + ctx.getBeanDefinitionCount());

✅ 6. Can you have multiple beans of the same type? How does Spring know which one to inject?

✔️ Answer:

Yes, and you can resolve conflicts using:

  • @Primary – Marks a bean as default

  • @Qualifier("beanName") – Specifies the exact bean to inject


✅ 7. What happens if two beans implement the same interface and no qualifier is used?

✔️ Answer:

Spring throws a NoUniqueBeanDefinitionException, because it doesn't know which bean to inject.


✅ 8. What’s the difference between @Bean and @Component?

✔️ Answer:

@Component@Bean
Used on classesUsed on methods inside @Configuration
Automatically discoveredExplicitly declared
Can't customize easilyFine-grained control of object creation

✅ 9. How do you define a lazy-loaded bean?

✔️ Answer:

Use @Lazy:


@Component @Lazy public class MyBean { ... }

Now Spring creates the bean only when it’s first requested, not at startup.


✅ 10. Can Spring Boot manage third-party objects (e.g., not annotated with @Component)?

✔️ Answer:

Yes! Register them using @Bean:


@Configuration public class AppConfig { @Bean public RestTemplate restTemplate() { return new RestTemplate(); } }

Spring will manage the lifecycle just like any other bean.


๐Ÿง  Bonus Tip: Must-Know Keywords for Interviews

"Spring Boot scans for beans using annotations like @Component. By default, it uses singleton scope, but we can switch to prototype or request. The container handles bean lifecycle and dependency resolution using IoC and DI principles."

 

๐ŸŒฑ How Objects (Beans) Are Created in Spring Boot – Explained with Examples

In Spring Boot, objects are managed by the Spring container and are known as beans. Unlike regular Java classes, Spring controls the creation, lifecycle, and scope of these objects.

In this blog, you’ll learn:

  • How objects are created in Spring Boot

  • How many instances are created

  • Bean scopes (singleton, prototype, etc.)

  • Real code examples


๐Ÿง  What Is a Spring Bean?

A Spring Bean is simply a Java object that is instantiated, assembled, and managed by Spring's IoC container.

You register a bean by using:

  • @Component

  • @Service

  • @Repository

  • @Controller

  • or manually via @Bean in a config class


✅ Default Object Creation – Singleton Scope

By default, Spring Boot creates only one instance of a bean per container. This is called the singleton scope.

๐Ÿ”ง Example:


@Component public class MyService { public MyService() { System.out.println("MyService bean created!"); } }

@RestController public class MyController { @Autowired private MyService service1; @Autowired private MyService service2; @GetMapping("/test") public String test() { return "Are both services same? " + (service1 == service2); } }

๐Ÿ’ก Output:

MyService bean created! Are both services same? true

Only ONE object is created, reused across the app.


๐Ÿ”„ Changing Scope: Prototype (New Object Every Time)

If you want a new object each time, use @Scope("prototype").

๐Ÿ”ง Example:


@Component @Scope("prototype") public class MyPrototypeService { public MyPrototypeService() { System.out.println("PrototypeService instance created!"); } }


@RestController public class TestController { @Autowired private ApplicationContext context; @GetMapping("/proto") public String test() { MyPrototypeService s1 = context.getBean(MyPrototypeService.class); MyPrototypeService s2 = context.getBean(MyPrototypeService.class); return "Are both prototype beans same? " + (s1 == s2); } }

๐Ÿ’ก Output:


PrototypeService instance created! PrototypeService instance created! Are both prototype beans same? false

Two objects created, one per request to getBean().


๐Ÿงช Other Bean Scopes

ScopeDescription
singleton(Default) One instance per Spring container
prototypeNew instance every time the bean is requested
requestOne instance per HTTP request (Web apps only)
sessionOne per HTTP session
applicationOne per ServletContext

๐Ÿง  How Are Beans Created Internally?

Internally, Spring Boot uses reflection and dependency injection:

  1. Scans for annotated classes using @ComponentScan

  2. Creates bean definitions (BeanDefinition)

  3. Resolves dependencies using constructor injection or field injection

  4. Manages lifecycle (@PostConstruct, @PreDestroy, etc.)


๐Ÿงฉ Example: Constructor Injection


@Component public class A { public A() { System.out.println("A created"); } } @Component public class B { private final A a; @Autowired public B(A a) { this.a = a; System.out.println("B created with A"); } }

Spring creates A first, then passes it to B automatically.


๐Ÿ‘จ‍๐Ÿ”ฌ How to List All Beans Created by Spring Boot?

Add this to main():


public static void main(String[] args) { ConfigurableApplicationContext ctx = SpringApplication.run(MyApp.class, args); String[] beans = ctx.getBeanDefinitionNames(); Arrays.sort(beans); for (String name : beans) { System.out.println(name); } }

✅ You'll see all objects created by Spring, including yours and internal framework beans.


๐Ÿ” Singleton vs Prototype – When to Use?

Use CaseScope to Choose
Shared service (e.g. logging)singleton
Non-thread-safe objectsprototype
Per-user/session customizationrequest/session

๐Ÿ“Œ Summary

  • Spring Boot uses annotations to create and manage objects (beans)

  • By default, each bean is a singleton

  • You can change the scope with @Scope("prototype") and others

  • Spring handles injection, lifecycle, and reuse for you


๐Ÿง  Bonus Tip for Interviews

๐Ÿ—ฃ “In Spring Boot, object creation is driven by annotations and classpath scanning. Beans are typically singletons, but we can switch to prototype or request scope as needed. Spring uses dependency injection and reflection to wire dependencies automatically.”


Happy Learning :) 

 

๐Ÿš€ What Happens When You Start a Spring Boot Project – Step-by-Step

Have you ever wondered what actually happens under the hood when you run a Spring Boot application? It looks simple on the surface, but a lot is going on behind the scenes.

In this post, I’ll walk you through each step in the Spring Boot startup process—from hitting "Run" to handling web requests.


๐ŸŸข 1. You Hit Run or Execute SpringApplication.run()

Your entry point looks like this:


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

Here’s what kicks off the magic.


⚙️ 2. Spring Boot Creates a SpringApplication Instance

Internally, Spring Boot creates an instance of SpringApplication.


SpringApplication app = new SpringApplication(MyApp.class);

It also sets up:

  • Environment

  • ApplicationContext

  • Banner

  • Listeners

  • Initializers


๐Ÿ—️ 3. Environment Is Prepared

Spring Boot prepares the environment by:

  • Loading system properties

  • Reading application.properties or application.yml

  • Setting up profiles (like dev, prod, etc.)

  • Merging environment variables

This is handled by ConfigFileApplicationListener.


๐Ÿ” 4. ApplicationContext Is Created

Depending on the project type, one of the following is created:

  • AnnotationConfigApplicationContext (non-web)

  • AnnotationConfigServletWebServerApplicationContext (web apps)


๐Ÿ”Ž 5. Component Scanning & Bean Definition

Spring Boot uses:

  • @ComponentScan to find @Component, @Service, @Repository, etc.

  • @Configuration to load custom configs

These classes are registered as Spring Beans in the ApplicationContext.


๐Ÿ”ง 6. Auto-Configuration via @EnableAutoConfiguration

Spring Boot checks all entries in:


META-INF/spring.factories

Example:


EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

It loads only the relevant configurations based on classpath dependencies.


๐Ÿงฑ 7. Embedded Server (like Tomcat) Starts

If it’s a web project, Spring Boot:

  • Auto-configures Tomcat (or Jetty, Undertow)

  • Registers DispatcherServlet

  • Binds server port (default 8080)

  • Starts the HTTP listener

No need to deploy a WAR file — it runs as a standalone JAR!


๐Ÿ”„ 8. ApplicationRunner or CommandLineRunner Executes

If your project has logic like this:


@Component public class MyRunner implements CommandLineRunner { public void run(String... args) { System.out.println("App started!"); } }

Spring Boot will run it after startup.


๐Ÿ–ฅ️ 9. Application Is Up and Ready!

You’ll see:


Started MyApp in 3.456 seconds Tomcat started on port(s): 8080 (http)

๐ŸŽ‰ Your app is now live at http://localhost:8080


๐ŸŒ 10. Request Handling Begins

From now on:

  • DispatcherServlet routes incoming HTTP requests

  • Controllers like @RestController respond to them


@RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello, Spring Boot!"; } }

๐Ÿง  Recap: Spring Boot Startup Flow


@SpringBootApplication ↓ SpringApplication.run() ↓ Prepare Environment & Context ↓ Load application.properties ↓ Component Scanning ↓ Auto-ConfigurationStart Embedded Server ↓ Initialize Beans ↓ Run ApplicationRunner / CommandLineRunner ↓ App is READY to Handle Requests

Happy Learning :)

 

๐Ÿ” 10 Tricky Spring Boot Internal working Interview Questions You Must Know (with Answers)

Spring Boot makes life easier for developers, but interviewers love to dig into what happens under the hood. If you're preparing for a Spring Boot interview, these tricky questions and answers will give you an edge!


✅ 1. What exactly happens when you call SpringApplication.run()?

When you invoke SpringApplication.run():

  • It creates and configures the ApplicationContext

  • Loads application.properties or .yml configuration files

  • Registers ApplicationListeners and ApplicationInitializers

  • Performs component scanning

  • Triggers auto-configuration via @EnableAutoConfiguration

Pro Tip: Mention that it uses SpringFactoriesLoader to load configuration classes from META-INF/spring.factories.


✅ 2. How does Spring Boot decide which configuration class to load automatically?

Spring Boot uses:


SpringFactoriesLoader.loadFactoryNames(EnableAutoConfiguration.class)

It loads class names from:


META-INF/spring.factories

Only those relevant to the current classpath dependencies are activated.


✅ 3. What is the difference between @SpringBootApplication and @EnableAutoConfiguration?

  • @SpringBootApplication is a meta-annotation that includes:

    • @Configuration

    • @ComponentScan

    • @EnableAutoConfiguration

  • Using only @EnableAutoConfiguration will not scan for beans.

๐Ÿ“Œ Tip: Interviewers often test if you understand this convenience wrapper.


✅ 4. If two auto-configuration classes try to create the same bean, who wins?

Spring Boot uses conditional annotations like:


@ConditionalOnMissingBean

This means:

  • If you define the bean manually → your bean wins

  • Otherwise, Spring uses the auto-configured one

This is how Spring Boot gives you full control to override.


✅ 5. How is DispatcherServlet registered without a web.xml?

Spring Boot uses auto-configuration:


DispatcherServletAutoConfiguration

Internally, it uses a ServletRegistrationBean to register the DispatcherServlet at runtime — no need for web.xml.


✅ 6. How can you disable a specific auto-configuration?

There are two ways:

a) Using exclude in @SpringBootApplication:


@SpringBootApplication(exclude = { DataSourceAutoConfiguration.class })

b) In application.properties:


spring.autoconfigure.exclude=
org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration

✅ 7. What if multiple application.properties files are found in the classpath?

Spring Boot loads properties in the following priority order:

  1. /config/application.properties

  2. /application.properties in root classpath

  3. External files via -Dspring.config.location=...

  4. Command-line arguments override all

This enables flexible configuration across environments.


✅ 8. Can you run a Spring Boot app without @SpringBootApplication?

Yes. Just use the equivalent annotations manually:


@Configuration @EnableAutoConfiguration @ComponentScan

But @SpringBootApplication is the cleaner, preferred approach.


✅ 9. How does Spring Boot determine if it's a web application?

Spring Boot checks the classpath:

  • If it finds spring-web, spring-webmvc, or ServletContext → it's a web app

  • Then it loads web-specific configurations like:

    • DispatcherServletAutoConfiguration

    • WebMvcAutoConfiguration


✅ 10. What happens if there is no application.properties or .yml?

Spring Boot still starts using default values, such as:

  • Port: 8080

  • Context path: /

  • Embedded H2 database (if JPA is on classpath)

  • Default error page at /error

But defining properties is essential for production-ready apps

 

How Spring Boot Works Internally – Step-by-Step with Real Example

Spring Boot makes it easy to create stand-alone, production-grade Spring applications with minimal configuration. But what really happens when you run a Spring Boot app?

Let’s break it down step-by-step with code and an easy-to-understand flow.


1. Application Entry Point – @SpringBootApplication


@SpringBootApplication public class MyApp { public static void main(String[] args) { SpringApplication.run(MyApp.class, args); } }
  • @SpringBootApplication is a meta-annotation that includes:

    • @Configuration – Marks this class as a source of bean definitions

    • @EnableAutoConfiguration – Tells Spring Boot to auto-configure beans

    • @ComponentScan – Enables scanning for components (@Component, @Service, etc.)


2. Bootstrapping with SpringApplication.run()

When SpringApplication.run(MyApp.class, args) is called:

  • It creates a SpringApplication instance

  • Prepares the environment and application context

  • Loads application.properties or application.yml

  • Registers listeners and initializers


3. Auto-Configuration Magic

Spring Boot looks into the META-INF/spring.factories file and loads @Configuration classes based on dependencies.

Example:


org.springframework.boot.autoconfigure.EnableAutoConfiguration=\ org.springframework.boot.autoconfigure.web.servlet.WebMvcAutoConfiguration,\ org.springframework.boot.autoconfigure.jdbc.DataSourceAutoConfiguration
  • If spring-web is present → WebMvcAutoConfiguration kicks in

  • If spring-boot-starter-data-jpa is present → JPA configurations are loaded


4. Embedded Server Starts Automatically

If it's a web app:

  • Tomcat is auto-configured and started by Spring Boot

  • No need for external WAR deployment


TomcatServletWebServerFactory factory = new TomcatServletWebServerFactory();

App runs on http://localhost:8080 by default


5. Bean Scanning and Registration

Spring Boot scans for annotations like:

  • @Component

  • @Service

  • @Repository

  • @RestController

And registers them as beans in the ApplicationContext.


6. Request Dispatching with DispatcherServlet

Spring Boot registers DispatcherServlet automatically for web apps.

Example Controller:


@RestController public class HelloController { @GetMapping("/hello") public String hello() { return "Hello from Spring Boot!"; } }

Request to /hello is handled by this method.


7. Application Ready

Once the context is loaded, Spring Boot triggers:

  • CommandLineRunner or ApplicationRunner if present

  • Prints a log like:

    Started MyApp in 3.456 seconds

Quick Example: Complete App


@SpringBootApplication public class BlogDemoApplication { public static void main(String[] args) { SpringApplication.run(BlogDemoApplication.class, args); } } @RestController class DemoController { @GetMapping("/") public String home() { return "Welcome to my blog!"; } }

Run it, and your app is live at http://localhost:8080/


Spring Boot Internals – Summary Flow


@SpringBootApplication ↓ SpringApplication.run() ↓ Load Properties & Beans ↓ Auto-Configuration via spring.factories ↓ Embedded Tomcat/Jetty Starts ↓ Component Scanning & Bean Registration ↓ DispatcherServlet Routes Requests ↓ App is Ready to Serve