🚀 Spring Boot Series – Part 6: What Happens When You Click the RUN Button in a Spring Boot Application? We do it every day: Write code → click Run → application starts. But what actually happens behind the scenes? 🤔 Let’s break it down step by step 👇 1️⃣ JVM starts the application When you click Run, the Java Virtual Machine (JVM) starts your Java program and looks for the main() method. 2️⃣ SpringApplication.run() gets executed This is the line that bootstraps the entire Spring Boot application. SpringApplication.run(MyApplication.class, args); 3️⃣ Spring Boot detects @SpringBootApplication Spring Boot detects the main annotation and understands that it needs to configure, auto-configure, and scan your application. 4️⃣ Spring Boot prepares the startup Spring Boot now prepares important things like: • ApplicationContext • Environment • Listeners • Initializers 5️⃣ ApplicationContext is created Spring creates the ApplicationContext, which is the Spring Container that manages all beans. 6️⃣ The environment is prepared Spring Boot reads configuration from: • application.properties / application.yml • Environment variables • Command-line arguments • Profiles 7️⃣ Component scanning and bean loading happen Spring scans classes annotated with: • @Component • @Service • @Repository • @Controller • @RestController • @Configuration It also processes @Bean methods and identifies what beans need to be created. 8️⃣ Auto Configuration kicks in Spring Boot checks the dependencies available on the classpath and automatically configures required beans. For example: • Web dependency → web-related beans • JPA dependency → data-related beans 9️⃣ ApplicationContext is refreshed At this stage, Spring actually starts creating beans, injecting dependencies, and initializing the application. This is where the application starts taking real shape in memory. 🔟 Embedded server starts If it is a web application, Spring Boot starts the embedded server (usually Tomcat). Now your application is capable of handling requests. 1️⃣1️⃣ Application is fully ready At this point: ✔ Beans are created ✔ Dependencies are injected ✔ Configuration is loaded ✔ Server is running 👉 Your Spring Boot application is now ready to serve requests. 🎯 Key Takeaway When you click Run, Spring Boot does much more than just execute your code. 👉 It creates the Spring container, reads configurations, scans components, applies auto-configuration, creates beans, injects dependencies, starts the server, and prepares the application to serve requests. Have you ever explored what actually happens inside SpringApplication.run() before? 🔍 In the next post of this series, we’ll explore Maven. Stay tuned. 💡 Save this post for future reference if you found it helpful. #SpringBoot #SpringFramework #Java #BackEndDevelopment #SoftwareEngineering #Programming #TechCommunity
Spring Boot Series: What Happens When You Click Run
More Relevant Posts
-
Java Spring Boot Annotations in a Nutshell https://lnkd.in/g7BmyE3E A technical overview of the essential Java Spring Boot Annotations, serving as a comprehensive "nutshell" guide for modern backend development. As Spring Boot continues to dominate the enterprise ecosystem, mastering its annotation-driven configuration is critical for building scalable, decoupled, and maintainable microservices. => Core Framework Annotations: Analyzing @SpringBootApplication, @Component, and @Bean for managing application context and dependency injection. => Web and REST Integration: Demonstrating the use of @RestController, @RequestMapping, and @PathVariable to streamline API development. => Data and Configuration: Leveraging @Service, @Repository, and @Value to enforce clean architectural layers and externalize properties. #codechallenge #programming #CODE #Coding #code #programmingtips #java #JAVAFullStack #spring #springframework #Springboot #springbootdeveloper #Maven #gradle #annotations #controller #service #dependencyInjection
To view or add a comment, sign in
-
I built Spring Perf Analyzer — because performance bugs are cheap to fix in dev and expensive to debug in prod. Most teams find N+1 queries, missing caches, and slow service calls through production incidents. This moves that discovery into your local development loop — zero infrastructure, one annotation. ⚙️ Zero-Friction Setup Step 1 — Drop the dependency. Step 2 — Add @EnablePerfAnalyzer to your main class. One annotation. Spring Boot's auto-configuration does the rest — the full instrumentation stack registers itself into your application context on startup. No XML. No manual wiring. No agent. No sidecar. Start your application. Every request is now instrumented. 🔧 How It Works Under the Hood Each layer was chosen because it's the earliest possible interception point for that class of problem: Hibernate StatementInspector sits at the JDBC boundary — before execution. Queries are tracked per-request via ThreadLocal, then analyzed post-request for structural repetition. That's where N+1s live, and that's exactly where they're caught. MVC HandlerInterceptor stamps request entry and exit timestamps directly into request attributes. No object allocation. No thread contention. Accurate latency measurement with negligible overhead. AspectJ @Around Advice wraps every @Service method and tracks invocation frequency against parameter signatures. A method called 3+ times with identical arguments, each taking over 100ms — that's not a coincidence. That's a missing cache, and it gets flagged with the exact method signature. Servlet Filter coordinates the entire analysis at the request boundary. After the response completes, findings are pushed to a non-blocking report queue. Your latency numbers stay clean. 🆚 Why This, and Not What You Already Have Datadog and New Relic are built for production — they need infrastructure, agents, and an incident to justify the signal. Hibernate's show_sql gives you a wall of text with no aggregation. Actuator surfaces metrics, not root causes. None of them are designed to give you actionable, request-scoped diagnostics inside a local dev loop with nothing to configure. That's the gap. This fills it. 📈 What's Next Thread pool saturation detection → JFR-based memory allocation profiling → CI/CD performance regression gates → Prometheus metrics export The direction is the same throughout: make performance observable by default, not discoverable by accident. Stack: Java 17 | Spring Boot 3.2.3 | Hibernate StatementInspector | AspectJ | HandlerInterceptor | Maven
To view or add a comment, sign in
-
🚀 Spring Boot in Real Projects — Day 5 One thing that confuses almost every beginner: 👉 How does data actually come from frontend to backend? If you don’t get this clearly, Spring Boot will always feel confusing. Let’s simplify it 👇 💡 3 Ways Data Comes from Frontend In real projects, frontend sends data in 3 common ways: @PathVariable @RequestParam @RequestBody Each one is used in a different situation. 🔹 1. @PathVariable This is used when data comes directly in the URL. Example: /users/101 @GetMapping("/users/{id}") public String getUser(@PathVariable int id) { return "User ID: " + id; } 👉 When you hit /users/101, the value 101 is passed as id. Use this when: ->You are working with a specific resource ->The value is required Example: Get user by ID Delete user 🔹 2. @RequestParam This is used when data comes as query parameters. Example: /users?name=Rajesh @GetMapping("/users") public String getUserByName(@RequestParam String name) { return "User Name: " + name; } 👉 Here, name=Rajesh is passed as a parameter. Use this when: ->Data is optional ->You are filtering or searching. Example: Search users Apply filters 🔹 3. @RequestBody This is used when data is sent in JSON format (mostly in POST/PUT requests). { "name": "Rajesh", "age": 22 } @PostMapping("/users") public String createUser(@RequestBody User user) { return "User created: " + user.getName(); } 👉 Spring automatically converts JSON → Java object. Use this when: ->You are sending full data ->Creating or updating something. Example: Register user Update profile. 🔄 How it looks in real life Frontend sends: GET /users/101 → handled by @PathVariable GET /users?name=Rajesh → handled by @RequestParam POST /users with JSON → handled by @RequestBody. #springbootseries #java
To view or add a comment, sign in
-
-
**Adopting Quarkus after years of Spring Boot** After years working with Spring Boot, I recently started using Quarkus on real projects. Not just hype. The shift is deeper and architectural. At first glance, both solve the same problems: REST, DI, persistence, security, cloud. But the real difference is not features. It’s when errors appear and how predictable the system is. Spring Boot is flexible and runtime-driven (auto-config, scanning, reflection). You move fast, but some issues appear late (integration or prod). Quarkus flips the model: build-time first, fail fast, less implicit behavior, more deterministic system. It validates early: • injection • configuration • wiring • integrations Result: less runtime logic, fewer surprises. --- **Build-time vs runtime (real impact)** Spring → validates late Quarkus → validates early In practice: • missing config → build error • invalid JPA mapping → early detection • ambiguous injection → build fails Dev loop changes completely. Spring: fast start, delayed issues Quarkus: stricter start, immediate feedback --- **Minimal example** Spring Boot: @Service class PaymentServiceV1 {} @Service class PaymentServiceV2 {} @Autowired PaymentService service → app starts → ambiguity handled later Quarkus: @ApplicationScoped @Named("v1") class PaymentServiceV1 {} @ApplicationScoped @Named("v2") class PaymentServiceV2 {} @Inject PaymentService service → build fails immediately Fix: @Inject @Named("v1") PaymentService service Same feature: Spring tolerates Quarkus enforces --- **What changes in practice** • clearer dependencies • fewer hidden bugs • faster debugging • more stable production At first: more friction Then: more control --- **Architecture impact** Spring: • runtime-heavy • implicit behavior • strong ecosystem Quarkus: • deterministic • explicit wiring • reduced reflection (native friendly) --- **Execution model** Spring (MVC): • blocking • 1 thread per request Quarkus: • reactive + non-blocking (Vert.x) • better scalability if used correctly But: blocking code in non-blocking flow = performance issues --- **Persistence** Both use Hibernate. Spring: • repository pattern • flexible Quarkus (Panache): • less boilerplate • faster for simple CRUD • needs discipline --- **Cloud & native** Spring = cloud compatible Quarkus = cloud-native by design • fast startup • low memory • native (GraalVM) ready --- **Reality check** Spring: • huge ecosystem • best for complex/legacy Quarkus: • more predictable • better for microservices But requires: • discipline • understanding of model --- **My takeaway** Not about performance. It’s about predictability. Less “why in prod?” More “I know why” --- Have you tried Quarkus in production? --- #Java #Quarkus #SpringBoot #Backend #SoftwareArchitecture #Microservices #CloudNative #GraalVM #TechLead #SoftwareEngineering
To view or add a comment, sign in
-
-
[DevNote] Re-skill from SpringBoot to .Net Quick Quick . . . VS Studio <-> IntelliJ NuGet [packages.config] (nuget.org) <-> Maven [pom.xml] / Gradle [build.gradle] (mvnrepository.com) VS_Project [config.ini] (Controller[WinForm] *.cs, View[WinForm] *.Designer.cs) <-> Root Package [applicaiton.yml] ([JavaFX/Swing] *.java, [JForm] *.form) VS_Project.View[Web] (*.asp/*.cshtml/*.aspx, Blazor) <-> Resources/View Package (*.jsp/*.xhtml/*.jspx, JSF) VS_Project.Middleware[Web] <-> ServletFilter/ControllerAdvide Package VS_Project.Controller[Web] (ActionFilter) <-> Controller Package (AOP) VS_Project.Common <-> Constant/Config Package VS_Project.Service (Decorator/Proxy) <-> Service Package (AOP) VS_Project.DAL <-> Repository Package (EF_CORE.LINQ : HIBERNATE.JPA, DbContext/ADO.NET : JDBC) VS_Project.Model <-> Entity Package /// OPTION 1 - TransactionScope using (var scope = new TransactionScope( TransactionScopeOption.Required, new TransactionOptions { IsolationLevel = IsolationLevel.ReadCommitted })) { // CALL MANY DAL / SERVICE _orderDal.InsertOrder(order); _certificateDal.UpdateGeneratePdfFlag(id, "Y"); _mailDal.InsertMailQueue(order); // COMMIT scope.Complete(); } // If throw exception → auto rollback /// OPTION 2 - TransactionScope (Async) using (var scope = new TransactionScope( TransactionScopeAsyncFlowOption.Enabled)) { await DoDbWorkAsync(); scope.Complete(); } /// OPTION 3 - EF6 DbContextTransaction using (var db = _dbFactory.CreateDbContext()) using (var tx = db.Database.BeginTransaction()) { try { db.SEC_USER.Add(user); db.SaveChanges(); db.OTHER_TABLE.Add(entity); db.SaveChanges(); tx.Commit(); } catch { tx.Rollback(); throw; } } /// OPTION 4 - OracleTransaction / ADO.NET var conn = new OracleConnection(cs); conn.Open(); var tx = conn.BeginTransaction(); try { // ExecuteCommand tx.Commit(); } catch { tx.Rollback(); } Noted : https://lnkd.in/ggpnYYSM
To view or add a comment, sign in
-
Wanted to share a few learnings from a recent backend upgrade we did. ⚙️ We moved one of our services to a newer Java, Spring, and Hibernate stack, and one thing became very clear: Big upgrades usually don’t fail at the compiler boundary. They fail at the assumption boundary. For us, the real work was not just the JDK upgrade. It was aligning everything around it: persistence mappings date/time behavior JSON serialization One of the earliest signals came from date/time handling. Before moving to java.time, we saw that some flows still using legacy java.sql.* types were not behaving correctly after the upgrade. In multiple cases, timestamp values were ending up in the database as 00:00:00.000 instead of carrying the expected time component. That created major issues across dev env because downstream flows were now reading and acting on incomplete or incorrect timestamps. That was the point where it became clear: this was not just a framework upgrade problem. It was a type-system and consistency problem. So we moved legacy JDBC-era date/time handling toward java.time, especially LocalDateTime. Java 21 does not suddenly reject java.sql.Date or java.sql.Timestamp, but modern frameworks definitely favor java.time. And with Hibernate 6.6.x, that path is much cleaner and more predictable. Why that mattered: older java.sql.* types were still “working” in parts of the system, but they became a poor fit across the full stack, especially once we looked at: ORM mappings Redis serialization integration flows consistency of behavior across layers The second issue was quieter, but just as important. 🧩 Once LocalDateTime entered one of our Redis-backed JSON flows, serialization started failing with: InvalidDefinitionException: Java 8 date/time type `java.time.LocalDateTime` not supported by default The root cause was a custom ObjectMapper. The fix: OBJECT_MAPPER.registerModule(new JavaTimeModule()); OBJECT_MAPPER.disable(SerializationFeature.WRITE_DATES_AS_TIMESTAMPS); Why this mattered: JavaTimeModule teaches Jackson how to handle java.time types disabling WRITE_DATES_AS_TIMESTAMPS makes unannotated date/time fields serialize as readable strings by default instead of timestamp/array-style output In short: the upgrade exposed hidden consistency gaps. The API layer may be fine, but caches, async flows, and internal serializers can still be operating under very different assumptions. A few takeaways from this upgrade 👇 JDK upgrades are often the easy part date/time migration deserves first-class attention Hibernate 6.6.x is far happier when your model uses java.time custom ObjectMappers are hidden compatibility surfaces consistency across DB, API, cache, and integrations matters more than “it compiles” #Java21 #SpringBoot #Hibernate #BackendEngineering #SoftwareArchitecture #TechLearning
To view or add a comment, sign in
-
🚀 Day 46: Mastering Data Binding in Spring MVC Continuing my Java Developer journey! Today was all about understanding how data moves from the frontend to my controllers and back. I spent the day diving deep into Spring MVC’s data handling capabilities. Here’s a breakdown of what I covered: @RequestParam vs. @PathVariable: Learned when to use Query Parameters (e.g., ?id=101) versus Path Variables (e.g., /user/101) to capture dynamic data from URLs. Data Binding (1-Way & 2-Way): 1-Way: Passing data from the Controller to the View using the Model object. 2-Way: Using Spring’s form handling to keep the View and the Model in sync, making form submissions seamless. Spring Tag Library: Explored how to use specialized JSP tags to bind form elements directly to Java objects, reducing boilerplate code and improving type safety. Seeing these pieces click together makes building web applications feel much more intuitive. Onward to Day 47! 👨💻 #Java #SpringFramework #SpringMVC #WebDevelopment #Backend #JavaDeveloper #LearningJourney #CodingLife #Telusko Hyder Abbas Naman Pahariya
To view or add a comment, sign in
-
-
Coming from a Java + Spring Boot background, I’ve built and consumed REST APIs for years. Recently, while experimenting with FastAPI, I stumbled upon a subtle but very interesting difference in how request routing works—and it genuinely made me pause and think. Consider this scenario: In FastAPI, if you define routes like: /books/{book_title} /books/harry and you place the dynamic route first, a request to /books/harry will be handled by the dynamic path, not the static one. Why? 👉 FastAPI resolves routes in the order they are defined. The first matching route wins—even if a more specific route exists later. As a Java developer, this felt counter‑intuitive at first. In Spring Boot, the framework does things differently: Routes are not resolved by order Spring calculates path specificity A static route like /books/harry will always win over /books/{bookTitle}, regardless of how methods are ordered So the same API behaves differently across frameworks—not because one is wrong, but because of different design philosophies: FastAPI / Python → explicit, developer‑controlled, minimal magic Spring Boot / Java → convention‑driven, framework‑managed, intelligent dispatching 📌 Key takeaway for me: When working with FastAPI, route ordering matters. Static routes should be defined before dynamic ones to avoid unexpected behavior. This small difference reinforced something important: Understanding the framework internals matters just as much as knowing the language. Learning new stacks like FastAPI as a Java developer has been both refreshing and humbling—and these nuances are what make the journey exciting. Curious to hear from others who’ve switched between ecosystems—what surprised you the most? #Java #SpringBoot #FastAPI #Python #BackendDevelopment #RESTAPI #LearningJourney #SoftwareEngineering
To view or add a comment, sign in
-
🚀 How Java Records Fit into a Clean Spring Boot Architecture (End-to-End) By now, we’ve covered: What records are Where they work Where they break (JPA entities ❌) Now let’s connect everything into a real backend architecture. 🧠 The problem most projects have Typical messy flow: Controller → Entity → Response 👉 Issues: Over-fetching data Exposing internal DB structure Tight coupling Hard to scale 🔥 Modern approach (used in production systems) Entity (JPA) ↓ Projection / Internal DTO (Record) ↓ API DTO (Record) 👉 Clear separation of concerns. 🧱 Step 1: Entity (Persistence layer) @Entity class UserEntity { @Id Long id; String name; String email; } ✔ Mutable ✔ Managed by Hibernate 📦 Step 2: Projection (Record) public record UserInternal(Long id, String name, String email) {} Repository: @Query(""" SELECT new com.app.UserInternal(u.id, u.name, u.email) FROM UserEntity u """) List<UserInternal> findAllUsers(); ✔ Fetch only required fields ✔ No entity tracking ✔ High performance 🔄 Step 3: API DTO (Record) public record UserResponse(String name) {} 👉 External contract (what client sees) 🔁 Step 4: Mapping (MapStruct) @Mapper(componentModel = "spring") public interface UserMapper { UserResponse toResponse(UserInternal user); } ✔ Clean conversion ✔ No manual boilerplate 🌐 Step 5: Controller @RestController @RequiredArgsConstructor class UserController { private final UserRepository repo; private final UserMapper mapper; @GetMapping("/users") public List<UserResponse> getUsers() { return repo.findAllUsers() .stream() .map(mapper::toResponse) .toList(); } } ⚡ Why this architecture is powerful ✅ 1. No unnecessary data loading 👉 You fetch only what you need ✅ 2. No entity exposure 👉 Database model ≠ API contract ✅ 3. Immutable data flow Records at every boundary No accidental mutation ✅ 4. Better performance No Hibernate tracking overhead No lazy loading surprises ✅ 5. Cleaner mental model Each layer has one responsibility: Entity → persistence Record → data transfer Mapper → transformation ⚠️ Common mistake Controller → Entity → JSON ❌ 👉 Leads to: N+1 queries security issues tight coupling 🧠 Senior-level insight The biggest benefit of records is not syntax… It’s enforcing clean boundaries between layers 💡 Final mental model Entity = database truth (mutable) Record = data contract (immutable) Mapper = bridge between worlds 🚀 Final takeaway Records shine when used as boundaries, not core domain objects If your architecture is clean, Records make it predictable, safe, and scalable. #Java #JavaRecords #SpringBoot #Hibernate #JPA #MapStruct #BackendDevelopment #SystemDesign #SoftwareEngineering #CleanArchitecture
To view or add a comment, sign in
-
☕ How Java Actually Works — from source code to running application. Most developers use Java daily without knowing this. After 10+ years of building enterprise Java systems, understanding what happens under the hood has made me a dramatically better engineer. Let me walk through every stage 👇 📝 Stage 1 — Source You write Java code in your editor — IntelliJ, VS Code, Eclipse. That code is saved as a .java source file. Human-readable. Platform-specific to nothing yet. This is where it all begins. ⚙️ Stage 2 — Compile The Java Compiler (javac) transforms your .java source file into Bytecode — a .class file. This is the magic of Java's "Write Once Run Anywhere" promise. The bytecode is not native machine code — it's an intermediate language that any JVM on any platform can understand. Windows, Linux, Mac — same bytecode runs everywhere. 📦 Stage 3 — Artifacts The compiled .class files are packaged into artifacts — JAR files, modules, or classpath entries. In enterprise projects I've shipped across Bank of America and United Health, Maven and Gradle manage this — producing versioned artifacts deployed to Nexus or AWS CodeArtifact repositories. 📂 Stage 4 — Load The Class Loader loads .class files, JARs, and modules into the Java Runtime Environment at runtime. Three built-in class loaders handle this — Bootstrap, Extension, and Application. Understanding class loading has helped me debug NoClassDefFoundError and ClassNotFoundException in production more times than I can count. 🔍 JVM — Verify Before executing a single instruction, the JVM Verifier checks the bytecode for correctness and security violations. No invalid memory access. No type violations. No corrupted bytecode. This is one reason Java is inherently safer than languages with direct memory management. ▶️ Stage 5 — Execute — Interpreter + JIT Compiler This is where performance gets interesting. The JVM first Interprets bytecode line by line — fast startup, moderate throughput. Simultaneously it monitors execution and identifies hot paths — code that runs frequently. Those hot paths are handed to the JIT (Just-In-Time) Compiler which compiles them to native machine code stored in the Code Cache. 🏃 Stage 6 — Run The JVM runs a mix of interpreted bytecode and JIT-compiled native code — balancing startup speed with peak performance. Standard Libraries (java.* / jdk.*) provide everything from collections to networking to I/O throughout execution. #Java #c2c #opentowork #c2h #JVM #CoreJava #JavaDeveloper #SpringBoot #JVMPerformance #FullStackDeveloper #OpenToWork #BackendDeveloper #Java17 #HiringNow #EnterpriseJava #SoftwareEngineer #JITCompiler #JavaInterview #CloudNative #Microservices #TechEducation #Programming
To view or add a comment, sign in
-
Explore content categories
- Career
- Productivity
- Finance
- Soft Skills & Emotional Intelligence
- Project Management
- Education
- Technology
- Leadership
- Ecommerce
- User Experience
- Recruitment & HR
- Customer Experience
- Real Estate
- Marketing
- Sales
- Retail & Merchandising
- Science
- Supply Chain Management
- Future Of Work
- Consulting
- Writing
- Economics
- Artificial Intelligence
- Employee Experience
- Workplace Trends
- Fundraising
- Networking
- Corporate Social Responsibility
- Negotiation
- Communication
- Engineering
- Hospitality & Tourism
- Business Strategy
- Change Management
- Organizational Culture
- Design
- Innovation
- Event Planning
- Training & Development