Backend•Jun 2026•3 min read

Annotation Based Configuration vs Xml Configuration

The decisive verdict on configuring Spring (and frameworks like it) with annotations in your code versus externalized XML files. One reads like the year it was written. The other is how anyone sane ships today.

The short answer

Annotation Based Configuration over Xml Configuration for most cases. Annotations put the wiring next to the code it wires, kill the file-to-class context switch, and are how every modern Spring Boot app is actually built.

  • Pick Annotation Based Configuration if building anything new on Spring, Jakarta, or any DI framework born after 2010 — @Component, @Autowired, @Configuration, done
  • Pick Xml Configuration if maintain a legacy app already drowning in XML and a rewrite is not on the table, or you genuinely need to swap config without recompiling
  • Also consider: A thin XML or @Configuration layer for the rare beans you do not own (third-party classes you cannot annotate) — that is the one place XML still earns its keep.

— Nice Pick, opinionated tool recommendations

The Short Answer

Annotation based configuration wins, and it is not close in 2026. Spring Boot — the way essentially everyone writes Spring now — is annotation-first by default. You drop @RestController on a class, @Autowired on a field, @Configuration on a beans file, and the framework wires it. XML configuration was the original Spring contract: every bean declared in applicationContext.xml, wiring spelled out in angle brackets, fully decoupled from the Java. That decoupling sounded principled and aged into a liability. The industry voted with its feet a decade ago. New projects that reach for XML config are either cargo-culting an old tutorial or stuck in a codebase nobody dares touch. If you are starting fresh and even considering XML, stop. The only honest reason to write it today is that someone already wrote it before you got there.

Where XML Actually Hurts

The core sin of XML configuration is distance. Your bean lives in UserService.java; its wiring lives in a 600-line XML file three directories away. To understand one object you read two files and pray they agree. Rename a class and the XML silently rots — no compiler catches it, you find out at startup with a BeanCreationException that points at a string. There is no autocomplete worth the name, no type checking, no refactoring tool that follows a bean reference across the boundary cleanly. Spelling 'com.example.service.UserServiceImpl' by hand is a typo waiting to ruin your afternoon. XML defenders cite 'configuration without recompilation,' which matters for roughly one percent of beans and is the only argument with a pulse. Everything else is verbosity dressed up as discipline. It does not scale; it sprawls.

Where Annotations Earn It

Annotations keep the wiring where the code is. @Autowired sits on the field it injects; @Service sits on the class it registers. One file, one truth, full IDE support — autocomplete, compile-time checks, refactors that actually follow through. Component scanning means you stop hand-registering beans entirely; the framework finds them. The result is dramatically less ceremony and a far shorter path from 'I see a bug' to 'I see the cause.' The fair critique: annotations couple config to source, so you cannot retune a third-party class you do not own, and 'magic' wiring can hide what is happening until something fails to resolve. Both are real. Neither outweighs reading one file instead of three. The escape hatch — @Configuration classes — gives you explicit, type-safe, testable Java wiring for the genuinely awkward cases without crawling back to XML.

The Honest Caveat

This is not a religion, so do not turn it into one. The best real-world Spring apps are annotation-dominant with a deliberate sliver of explicit config. Beans for classes you import from a library — a DataSource, a third-party client, a Jackson ObjectMapper you want tuned — cannot be annotated because you do not own the source. That is exactly what an @Configuration class with @Bean methods is for: explicit, type-checked, refactor-safe, and still living in Java where your tools can see it. If you are on a frozen legacy system, leave the XML alone; rewriting working config for ideological tidiness is how you ship regressions for no business reason. And do not over-annotate either — scattering @Autowired on fields instead of constructors makes testing harder and hides dependencies. Annotations win the war. Use them like an adult, not a zealot, and reach for @Configuration before you ever reopen an XML file.

Quick Comparison

FactorAnnotation Based ConfigurationXml Configuration
Wiring localityConfig sits on the class it configures — one file to readConfig externalized to separate XML files, often far from the code
Compile-time safetyType-checked, refactor-aware, IDE autocomplete worksString-based references; errors surface only at startup
Configuring third-party classes you don't ownCan't annotate source you don't control; needs @ConfigurationDeclares any class by fully-qualified name, no source access needed
Verbosity / boilerplateMinimal; component scanning auto-registers beansEvery bean and dependency spelled out in angle brackets
Modern ecosystem fitDefault for Spring Boot and every current frameworkLegacy-only; new projects rarely choose it

The Verdict

Use Annotation Based Configuration if: You are building anything new on Spring, Jakarta, or any DI framework born after 2010 — @Component, @Autowired, @Configuration, done.

Use Xml Configuration if: You maintain a legacy app already drowning in XML and a rewrite is not on the table, or you genuinely need to swap config without recompiling.

Consider: A thin XML or @Configuration layer for the rare beans you do not own (third-party classes you cannot annotate) — that is the one place XML still earns its keep.

🧊
The Bottom Line
Annotation Based Configuration wins

Annotations put the wiring next to the code it wires, kill the file-to-class context switch, and are how every modern Spring Boot app is actually built. XML's "central config" virtue evaporated the moment you needed three open files to trace one bean. Pick annotations and never look back.

Related Comparisons

Disagree? nice@nicepick.dev