CodeGym /Courses /Spring Boot /The entry point of a Boot application

The entry point of a Boot application

Spring Boot
Level 1, Lesson 4
Available

1. A small main(), but a lot of work️

Let's look again at a familiar example, but this time not as something magical, rather as an object for analysis:

package com.example.catalogservice; 

import org.springframework.boot.SpringApplication; 
import org.springframework.boot.autoconfigure.SpringBootApplication; 

@SpringBootApplication // mark it: this is the main class from which context assembly begins
public class CatalogServiceApplication {

    public static void main(String[] args) {
        // Start the application through Boot: it will assemble the context, apply auto-configurations, etc.
        var context = SpringApplication.run(CatalogServiceApplication.class, args);

        // Simple marker: the context really started and is in an active state
        System.out.println("Context active = " + context.isActive());

        // How many bean definitions are registered in the context (infrastructure + your components)
        System.out.println("Bean definitions = " + context.getBeanDefinitionCount());
    }
}

At the first level, this class tells us several important things 👀 First, the application has a clear entry point. Second, startup is delegated not to your business logic, but to the platform mechanism SpringApplication.run(...). Third, the result of this startup is not just "the code ran", but a live ApplicationContext.

Pay attention to the last line with the number of bean definitions. Even in a very small application, this number is often unexpectedly large — hundreds of beans are not uncommon 😮 And that is exactly a very clear moment: you wrote a tiny main(), and Boot started a noticeable chunk of infrastructure around the application.

At this point, it is important not to get scared. A large number of beans does not mean that you are required to understand hundreds of classes today. It means something else: the platform really assembles the application environment, rather than just calling your method and moving on 🧩

That is why run() cannot be treated as "just another line in main()". This line starts the application's life as a system.

2. What does @SpringBootApplication mean? 🏷️

The @SpringBootApplication annotation is very often a victim of two extremes. People either treat it as a magic seal of "let everything work now", or try to poke into its tiny pieces too early and drown in the details. For the first level of our course, a third position is more useful: see its role without unnecessary mysticism.

At the current level, think of @SpringBootApplication as the starting marker of a Boot application. It shows the platform where application assembly begins and where the bootstrapping point is located. That is enough to read the main class meaningfully.

So there is no need yet to force yourself to memorize all the technical components of this annotation. What matters more is its function: it is a flag that tells Spring Boot, "here is the application that needs to be started as a single environment." That is why the main class usually lives close to the root of the packages — from there it is convenient to assemble the whole application 🌱

3. What does SpringApplication.run(...) actually do? 🛠️

Now to the most interesting call. What does SpringApplication.run(...) mean at first glance? It tells the platform: take this class as the starting point, assemble the application environment, create the ApplicationContext, apply startup settings, and if this is a web application, bring up the web runtime and keep the process alive as a service.

The word assemble is especially important here. Boot does not create an application out of thin air. It assembles it from the available Spring foundation, dependencies on the classpath, and its own default conventions. In other words, run() is not a "magic button for everything", but a startup and runtime assembly platform.

Several engineering surprises are already hidden in this call 💥

First, the application becomes not a set of disconnected objects, but a single context. Second, startup gets a clear observation point through logs. Third, a boundary appears between "the JVM just entered main()" and "the application has really started".

That is exactly why it is so useful to see run() once as a coordinate system, not just as a template line. As long as you treat it as a mandatory ritual, you have little support for diagnostics. As soon as you start seeing that it brings up the context, server runtime, and startup mechanisms, Boot suddenly becomes much more logical 🔧

4. Reading startup logs like a backend developer 🤦‍♂️

Let's break down the same startup through logs. Take a typical fragment:

:: Spring Boot ::

2026-03-10T10:15:41.120+03:00  INFO  Starting CatalogServiceApplication using Java 25
2026-03-10T10:15:41.122+03:00  INFO  No active profile set, falling back to 1 default profile: "default"
2026-03-10T10:15:42.203+03:00  INFO  Tomcat initialized with port 8080 (http)
2026-03-10T10:15:42.481+03:00  INFO  Root WebApplicationContext: initialization completed in 982 ms
2026-03-10T10:15:42.760+03:00  INFO  Tomcat started on port 8080 (http) with context path '/'
2026-03-10T10:15:42.781+03:00  INFO  Started CatalogServiceApplication in 1.944 seconds

The ASCII banner at the beginning is not just a decorative postcard. It is useful as a quick marker: you are indeed looking at the Boot startup of a specific application. In projects where several terminals are open at the same time, this is unexpectedly convenient.

Then comes the line Starting ... using Java .... This is the first clue: which class is starting and which JVM the application is running on. The next line about the profile shows which configuration mode it started with. For Boot, this is not a small thing, but an important part of the startup environment.

The Tomcat lines give a second major signal: if the application has a web baseline, the embedded server is initialized and is preparing to listen on a port. We do not yet need the whole discussion of where Tomcat came from. What matters is the fact itself: the service is bringing up the web runtime.

And finally, the line Started ... in ... seconds is the key readiness marker. Before it, the application may still be in the process of assembling the context. After it, Boot tells us: startup is complete, the context is up, and the application considers itself alive.

Startup logs are not noise, but a full dashboard for your service 🚦

5. Port, process, and service readiness

Now for the most useful distinction on day one: a process, a context, and service readiness are not the same thing.

- main() may have completed. But that does not yet mean the application has become a service.
- ApplicationContext may have started coming up. But that does not yet mean the web server is already listening on a port.
- The server may have initialized. But until you see the final successful startup and get an HTTP response, the picture is still incomplete.

That is why it is useful to check a live run in two ways. First, by looking at the logs. Then, with a simple external request:

# Send an HTTP request to the service started locally
curl -i http://localhost:8080/
# -i asks curl to show the response headers (so you can clearly see the code: 200/404/500, etc.)

If the server responds, even with 404 Not Found, that is already a very good sign. It means the application did not just start as a JVM process, but is actually accepting HTTP requests. If instead you get Connection refused, that is a different class of problem: the port is not listening, the server did not start, or the application crashed earlier.

This is how one of the most useful habits of a backend developer is born. Not saying "well, it seems to have started", but distinguishing levels of readiness. It sounds minor only on paper. In practice, this distinction saves a huge amount of time when debugging startup.

6. A little more about ApplicationContext

The word ApplicationContext sounds a bit threatening if you try to understand it in all its depth right away. For the first day, a very down-to-earth definition is enough: this is the central managed environment of a Spring application, where the application's objects live and are wired together.

When SpringApplication.run(...) returns context, that means the application did not just "do something in main()". It brought up the internal center of the system's life 🧩 So it is useful to print at least context.isActive(). This is a very simple, but meaningful marker: it confirms that the context is active and the application has really entered the working phase.

The second interesting moment is the call to getBeanDefinitionCount() 🚀 Even in a small project, you can see that there is already quite a lot of infrastructure life inside the application. This is a moment of trust in Boot: the platform does not just look nice from the outside, it really assembles a noticeable runtime around your code.

And here a honest and still unanswered question appears 🔍 Who creates all these objects? How do they end up inside the context? Why can they find each other? As long as this question has no answer, Boot remains a little magical. As soon as understanding of the container and DI appears, the magic starts turning into mechanics.

7. Spring Boot first-run table

Below is a short table worth saving. This is no longer just an explanation, but a practical template for reading the first startup of a Boot application.

Signal What it means If the signal is missing, what should you think about
Starting <AppName> ... the correct application class started and bootstrapping began maybe you are starting the wrong class, or the process dies too early
Line about profile (default or another one) the application selected a configuration mode maybe the expected arguments or environment variables were not picked up
Line about the server and port the web runtime is initializing and preparing to listen on a port maybe this is not a web application, or startup failed before server initialization
Started <AppName> in ... seconds the context is up, and Boot considers startup successful if the line is missing, the application likely crashed before reaching a ready state
HTTP response from localhost:8080 the service is really accepting requests if you see Connection refused instead, the problem is in startup or an occupied port

This table is useful because it gives you a ready-made sequence of observation 👌 First look at the startup class. Then at the profile. Then at the server and port. Then at successful completion. Then at the external HTTP response. That alone is enough to make the first startup no longer feel foggy.

If you want an even shorter formula for memory run() → logs → port → HTTP response.
As long as this chain reads confidently, you are already standing on a very good launch platform for further Boot analysis.

8. Typical mistakes 🎱

Mistake #1: treating SpringApplication.run(...) as "just a required template line".
That immediately takes away half of your understanding. run() is not decoration and not a random API call. It starts the application context and the entire startup environment. Until you see that, Boot will remain a ritual of copy-paste.

Mistake #2: thinking that if the console did not close, then the service is already ready.
An unfinished process is not yet a guarantee of readiness. Look at the logs, the port, and the external HTTP response. Only then does confidence appear that the application really became a service, rather than just hanging in an undefined state.

Mistake #3: treating the banner and startup logs as decorative noise.
In fact, these are the first and very useful signals of application state. They show the application name, profile, web runtime, port, and the fact that startup completed successfully. Ignoring them means voluntarily giving up the cheapest diagnostics.

Mistake #4: confusing 404 Not Found with "nothing works".
404 is a response from a started server. No connection at all is a completely different problem. If you distinguish these situations from day one, diagnosing any startup later becomes noticeably calmer.

Mistake #5: being scared of a large number of bean definitions and the word ApplicationContext.
A large number of components at startup does not mean you are "too dumb for Spring". It means Boot really assembled a serious runtime around the application. On the first day, you are not expected to know every detail. It is enough to see the principle itself: the application has started as a managed environment, and now the next honest question is who fills that environment and how.

1
Task
Spring Boot, level 1, lesson 4
Locked
Starting Through a SpringApplication Object
Starting Through a SpringApplication Object
1
Survey/quiz
Spring Boot, level 1, lesson 4
Unavailable
Spring Boot
Startup and application context
Comments
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION