{"post":{"slug":"how-to-learn-spring-boot-2026","title":"How to learn Spring Boot in 2026: Java microservices without the boilerplate","excerpt":"Spring Boot 3.4 with virtual threads and GraalVM native image makes Java competitive again for microservices. This 2026 guide gets you productive fast.","category":"code","date":"March 13, 2026","author":"ByteLedger Team","content":"<span class=\"dropcap\">S</span>pring Boot is the most widely deployed Java web framework in enterprise software, and in 2026 it is also competitive for greenfield microservices work thanks to two changes: virtual threads (Project Loom) making blocking code scale without async complexity, and GraalVM native image bringing startup times under 100 ms. If you work in Java or Kotlin and need to build production services, Spring Boot 3.4 is the pragmatic, well-supported choice.\n\n## What changed in 2026\n\n- **Virtual threads on by default.** Spring Boot 3.4 enables `spring.threads.virtual.enabled=true` by default. Your existing blocking JDBC calls, RestTemplate requests, and `@Service` methods now run on virtual threads — millions of concurrent requests without thread-pool tuning.\n- **Spring Boot 3.4 requires Java 21+.** JDK 21 LTS is the minimum. This means pattern matching (`switch` expressions, records, sealed classes) are first-class Java, not preview features.\n- **Spring Modulith 1.2 stable.** Modular monolith patterns with eventing between modules — the practical middle ground between monolith and microservices.\n- **Spring AI 1.0 GA.** First-class Spring integration with OpenAI, Anthropic, and local models (Ollama). Vector store support for pgvector and Chroma.\n\n## Project setup\n\nGo to [start.spring.io](https://start.spring.io) and select:\n- Project: Gradle (Kotlin DSL) or Maven\n- Language: Java (or Kotlin)\n- Spring Boot: 3.4.x\n- Dependencies: Spring Web, Spring Data JPA, PostgreSQL Driver, Spring Security, Validation\n\nOr via the CLI:\n\n```bash\ncurl https://start.spring.io/starter.zip \\\n  -d type=gradle-project \\\n  -d language=java \\\n  -d bootVersion=3.4.3 \\\n  -d dependencies=web,data-jpa,postgresql,security \\\n  -d javaVersion=21 \\\n  -o demo.zip && unzip demo.zip\n```\n\n## The core programming model\n\nSpring Boot auto-configures beans based on what is on the classpath. You declare components; the framework wires them:\n\n```java\n// Entity\n@Entity\n@Table(name = \"posts\")\npublic record Post(\n    @Id @GeneratedValue Long id,\n    @Column(nullable = false) String title,\n    boolean published\n) {}\n\n// Repository — no implementation needed\npublic interface PostRepository extends JpaRepository<Post, Long> {\n    List<Post> findByPublishedTrue();\n}\n\n// Service\n@Service\n@Transactional(readOnly = true)\npublic class PostService {\n    private final PostRepository repo;\n    PostService(PostRepository repo) { this.repo = repo; }  // constructor injection\n\n    public List<Post> published() { return repo.findByPublishedTrue(); }\n}\n\n// Controller\n@RestController\n@RequestMapping(\"/api/posts\")\npublic class PostController {\n    private final PostService service;\n    PostController(PostService service) { this.service = service; }\n\n    @GetMapping\n    public List<Post> list() { return service.published(); }\n}\n```\n\nRunning this with `./gradlew bootRun` produces a running API at `http://localhost:8080/api/posts`.\n\n## Virtual threads in practice\n\n```properties\n# application.properties\nspring.threads.virtual.enabled=true\nspring.datasource.hikari.maximum-pool-size=20\n```\n\nWith virtual threads, 20 database connections serve thousands of concurrent requests — the JVM creates a new virtual thread (lightweight, ~1 KB) per request instead of blocking a platform thread. No `Mono`, no `Flux`, no reactive operators required.\n\n## Configuration and profiles\n\n```yaml\n# application.yml\nspring:\n  datasource:\n    url: jdbc:postgresql://localhost:5432/mydb\n    username: ${DB_USER}\n    password: ${DB_PASS}\n  jpa:\n    show-sql: true       # remove in production\n    hibernate:\n      ddl-auto: validate # never \"create-drop\" in production\n\n---\nspring:\n  config:\n    activate:\n      on-profile: prod\n  jpa:\n    show-sql: false\n```\n\n## Framework comparison\n\n| Factor | Spring Boot | Quarkus | Micronaut |\n| --- | --- | --- | --- |\n| Ecosystem | Largest | Growing | Moderate |\n| Native image | GraalVM (good) | Excellent | Good |\n| Virtual threads | Yes (3.2+) | Yes | Yes |\n| Learning curve | High (rich) | Moderate | Moderate |\n| Enterprise adoption | Dominant | Growing | Niche |\n\n## How to pick\n\nUse Spring Boot when your organisation already deploys it, when you need the Spring Security ecosystem (OAuth2, SAML, LDAP), or when you are writing a long-running JVM service where startup time does not matter. Use Quarkus for Kubernetes-native work where native image startup time is critical.\n\n## Common mistakes\n\n**Using `@Autowired` field injection.** Constructor injection is preferred — it makes dependencies explicit and enables immutable beans. `@Autowired` on a field hides dependencies.\n\n**`ddl-auto: create-drop` in any shared environment.** This drops and recreates your database schema on every restart. Use Flyway or Liquibase for migrations; set `ddl-auto: validate`.\n\n**Catching `Exception` everywhere.** Use `@ControllerAdvice` with `@ExceptionHandler` to centralise error handling rather than wrapping every service call in try/catch.\n\n**Missing `@Transactional` on write operations.** Without `@Transactional`, each ORM operation is its own transaction. Multi-step writes that fail halfway leave partial data.\n\n## What to skip\n\n- **Spring MVC XML config.** `applicationContext.xml` is a relic of Spring 2. Annotation and Java config replaced it; do not learn it.\n- **Spring WebFlux (Project Reactor) for new services.** Virtual threads give you the scalability of reactive without the cognitive overhead of `Mono`/`Flux`. Use WebFlux only if you need backpressure or streaming responses.\n- **`RestTemplate`.** It is deprecated in Spring Boot 3. Use `RestClient` (synchronous, fluent) or `WebClient` (reactive) for HTTP calls.\n\n## FAQ\n\n**Spring Boot vs Quarkus in 2026?**\nSpring Boot for teams with existing Spring investment and complex security needs. Quarkus for Kubernetes-native workloads where native image performance matters most.\n\n**Do I need to know Spring Core before Spring Boot?**\nYou should understand dependency injection, beans, and the application context. Spring Boot auto-configuration hides most of it, but when something goes wrong, you need the mental model to debug it.\n\n**Kotlin or Java with Spring Boot?**\nKotlin is fully supported and removes a lot of Java verbosity (data classes replace records for mutable models, extension functions, coroutines for async). New teams often prefer Kotlin.\n\n**How do I deploy to Kubernetes?**\n`./gradlew bootBuildImage` produces an OCI-compliant container via Cloud Native Buildpacks — no Dockerfile required for standard apps. Then apply your Kubernetes manifests.\n\n## Where to go next\n\nAfter Spring Boot basics, explore [how to containerize an app in 2026](/blog/how-to-containerize-an-app-2026) for Docker and Kubernetes deployment, [how to build a REST API in 2026](/blog/how-to-build-a-rest-api-2026) for API design principles, and [how to set up a database in 2026](/blog/how-to-set-up-a-database-2026) for production PostgreSQL configuration.","hue":314,"metaTitle":"How to Learn Spring Boot in 2026","metaDescription":"Practical 2026 guide to learning Spring Boot 3.4. Covers virtual threads, Spring Data JPA, REST APIs, security, GraalVM native image, and production deployment.","keywords":["how to learn spring boot 2026","spring boot 3.4 tutorial","spring boot virtual threads","spring data jpa 2026","spring boot rest api","graalvm native image spring boot","spring boot microservices 2026","java web development 2026","spring boot vs quarkus 2026","spring boot production deployment"],"tldr":["**Virtual threads (Project Loom) change everything** — Spring Boot 3.2+ enables virtual threads with one property; your blocking code now scales like async code.","**Start with Spring Initializr** — never set up a Spring project by hand; the generator at start.spring.io produces a correct `pom.xml` or `build.gradle` instantly.","**Spring Data JPA + Hibernate hides complexity** — learn what queries it generates with `spring.jpa.show-sql=true` before you trust the abstraction.","**GraalVM native image cuts startup from seconds to milliseconds** — use it for functions and CLIs; stick with JVM for long-running services.","**Skip:** learning XML-based Spring configuration — annotation-driven and Java-config approaches replaced XML in Spring 4 (2013); do not touch it."],"readTime":"4 min read","wordCount":943},"related":[{"slug":"how-to-learn-java-2026","title":"How to learn Java in 2026: from first class to production-ready","excerpt":"Java 21+ is faster, more expressive, and far less verbose than its reputation suggests. This 2026 roadmap cuts the noise and shows you what actually matters.","category":"code","date":"March 13, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":316},{"slug":"spring-vs-quarkus-2026","title":"Spring vs Quarkus in 2026: choosing the right Java backend framework","excerpt":"Spring Boot is the enterprise Java default; Quarkus is the cloud-native challenger with native compilation. Here is the honest 2026 tradeoff guide.","category":"code","date":"March 3, 2026","author":"ByteLedger Team","readTime":"4 min read","hue":313},{"slug":"java-vs-kotlin-2026","title":"Java vs Kotlin in 2026: which JVM language should you use?","excerpt":"Kotlin is the preferred language for new Android apps and a growing force in backend development. Here is the honest 2026 case for when to use each.","category":"code","date":"April 6, 2026","author":"ByteLedger Team","readTime":"6 min read","hue":306}],"sameCategory":[{"slug":"bazel-build-explained-2026","title":"Bazel Explained: What Hermetic Builds Actually Cost","excerpt":"Bazel delivers reproducible, precisely cached builds and demands that you describe everything. Here is what you get, what it costs, and who should say no.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":145},{"slug":"graphql-federation-2026","title":"GraphQL Federation: One Graph, Many Teams","excerpt":"Federation composes independently-owned subgraphs into a single API. Here is what it solves, the operational cost it adds, and when a simpler gateway is enough.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":300},{"slug":"hermetic-builds-explained-2026","title":"Hermetic Builds Explained: Same Inputs, Same Output","excerpt":"A hermetic build depends only on declared inputs. Here is what that property gives you, the common leaks that break it, and how to move toward it incrementally.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":130},{"slug":"monorepo-tooling-compared-2026","title":"Monorepo Tooling Compared: What You Actually Need","excerpt":"Monorepo tools solve task orchestration and caching, not repository layout. Here is what each tier provides and how to tell when you have outgrown the simple option.","category":"code","date":"August 19, 2026","author":"ByteLedger Team","readTime":"3 min read","hue":150}],"newer":{"slug":"how-to-learn-r-programming-2026","title":"How to learn R programming in 2026: the data scientist path","excerpt":"R in 2026 is more productive than ever with Positron IDE, the tidyverse, and first-class Quarto integration. Here is the roadmap that skips the dead ends.","category":"code","date":"March 13, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":317},"older":{"slug":"how-to-learn-swift-2026","title":"How to learn Swift in 2026: the practical iOS and beyond roadmap","excerpt":"Swift is Apple''s primary language for iOS, macOS, and server-side apps, and it is increasingly used for cross-platform CLI tools. Here is the 2026 path.","category":"code","date":"March 13, 2026","author":"ByteLedger Team","readTime":"5 min read","hue":306}}