<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
  <title>Zero Duplications</title>
  <subtitle>Om systemutveckling, filosofi och AI.</subtitle>
  <link href="https://zero-duplications.com/sv/feed.xml" rel="self" type="application/atom+xml"/>
  <link href="https://zero-duplications.com/sv/"/>
  <updated>2026-09-01T00:00:00Z</updated>
  <id>https://zero-duplications.com/sv/</id>
  <author>
    <name>Ola Karlsson</name>
  </author>
  <entry>
    <title>Tänk om vi behövde färre ramverk?</title>
    <link href="https://zero-duplications.com/sv/posts/2026-09-01-mindre-ramverk-mer-java/"/>
    <updated>2026-09-01T00:00:00Z</updated>
    <id>https://zero-duplications.com/sv/posts/2026-09-01-mindre-ramverk-mer-java/</id>
    <summary>Ett försök att resonera kring när Spring Boot verkligen behövs och när vanlig Java 25 kan räcka — med ett förslag på beslutsordning.</summary>
    <content type="html">  &lt;p class=&quot;lead&quot;&gt;Under många år har Java-utveckling ofta betytt att vi lägger till ett ramverk eller bibliotek så fort ett nytt behov uppstår. Det har varit rationellt, och jag har gjort likadant. Men Java-plattformen har vuxit, språket har blivit bättre och priset för mekanisk kod har sjunkit. Därför har jag börjat fundera på en fråga jag inte har ett färdigt svar på: &lt;strong&gt;hur mycket av det vi brukar lägga till behöver vi fortfarande?&lt;/strong&gt;&lt;/p&gt;
  &lt;section class=&quot;section grid-2&quot;&gt;
    &lt;div class=&quot;copy&quot;&gt;
      &lt;p class=&quot;eyebrow&quot;&gt;01 · Tanken&lt;/p&gt;
      &lt;h2&gt;Det här handlar inte om att Spring är problemet&lt;/h2&gt;
      &lt;p&gt;Spring Boot löser många svåra problem, och gör det bra. För publika API:er, säkerhet, avancerad routing, observability och stora integrationsytor är Spring antagligen fortfarande det billigaste alternativet totalt sett.&lt;/p&gt;
      &lt;p&gt;Men Spring har blivit så självklart att jag misstänker att vi ibland når efter det även när problemet är mindre än lösningen. Det är den misstanken jag vill undersöka här.&lt;/p&gt;
      &lt;p&gt;En liten intern tjänst behöver kanske bara några HTTP-anrop, en databas, ett utgående anrop och lite affärslogik. I Java 25 finns redan HTTP-klient, JDBC, schemaläggning, records, loggning, JFR/JMX och moderna samtidighetsverktyg. Virtuella trådar gör dessutom vanlig, blockerande kod betydligt mer attraktiv för I/O än den var för några år sedan.&lt;/p&gt;
      &lt;div class=&quot;quote&quot;&gt;Java har inte blivit ett nytt Spring. Men kanske har gränsen för vad som behöver ett ramverk flyttat sig lite?&lt;/div&gt;
    &lt;/div&gt;
    &lt;figure class=&quot;figure&quot;&gt;
      &lt;img src=&quot;https://zero-duplications.com/assets/images/figure-01.webp&quot; alt=&quot;Abstrakt nätverksdiagram där en tydlig kärna kopplas till ett begränsat antal yttre system.&quot; /&gt;
      &lt;figcaption&gt;En målbild jag tycker är tilltalande: en tydlig kärna och ett litet antal medvetna gränser mot omvärlden.&lt;/figcaption&gt;
    &lt;/figure&gt;
  &lt;/section&gt;
  &lt;section class=&quot;section&quot;&gt;
    &lt;p class=&quot;eyebrow&quot;&gt;02 · Förvaltningsytan&lt;/p&gt;
    &lt;h2&gt;Kanske är beroenden lite av ett isberg&lt;/h2&gt;
    &lt;div class=&quot;grid-2&quot;&gt;
      &lt;div class=&quot;copy&quot;&gt;
        &lt;p&gt;När vi tittar på en &lt;code&gt;pom.xml&lt;/code&gt; eller &lt;code&gt;build.gradle&lt;/code&gt; ser vi bara en del av systemets tekniska yta. Under den finns transitiva bibliotek, versionskopplingar, autokonfiguration, proxyer, annotation processing och konventioner som någon behöver förstå den dagen något går fel.&lt;/p&gt;
        &lt;p&gt;Att räkna JAR-filer känns därför som ett trubbigt mått. En liten extern dependency kan vara mycket billig. Fyrahundra rader egen OAuth-kod kan vara mycket dyr.&lt;/p&gt;
        &lt;p&gt;&lt;strong&gt;Med minimalism menar jag alltså inte minst kod eller noll bibliotek.&lt;/strong&gt; Snarare mindre onödig semantik – mindre teknik som teamet behöver bära över tid.&lt;/p&gt;
      &lt;/div&gt;
      &lt;figure class=&quot;figure&quot;&gt;&lt;img src=&quot;https://zero-duplications.com/assets/images/figure-02.webp&quot; alt=&quot;Isberg där en liten synlig topp representerar direkta beroenden och en mycket större struktur under ytan representerar den dolda förvaltningsytan.&quot; /&gt;&lt;figcaption&gt;Direkta dependencies är den synliga delen. Min känsla är att förvaltningskostnaden ofta sitter i allt som följer med.&lt;/figcaption&gt;&lt;/figure&gt;
    &lt;/div&gt;
    &lt;div class=&quot;metrics&quot;&gt;
      &lt;div class=&quot;metric&quot;&gt;&lt;strong&gt;Versioner&lt;/strong&gt;&lt;span&gt;Uppgraderingar, kompatibilitet och koordinering.&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;metric&quot;&gt;&lt;strong&gt;Säkerhet&lt;/strong&gt;&lt;span&gt;CVE:er, parser- och nätverksyta, patcharbete.&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;metric&quot;&gt;&lt;strong&gt;Semantik&lt;/strong&gt;&lt;span&gt;Dolda regler, proxybeteenden och lifecycle.&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;metric&quot;&gt;&lt;strong&gt;Förändring&lt;/strong&gt;&lt;span&gt;Hur mycket behöver förstås nästa gång kraven flyttar sig?&lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;
  &lt;section class=&quot;section callout big&quot;&gt;
    &lt;p class=&quot;eyebrow&quot;&gt;03 · Ett förslag på ordning&lt;/p&gt;
    &lt;h2&gt;Tänk om vi frågade i den här ordningen?&lt;/h2&gt;
    &lt;p class=&quot;copy&quot;&gt;I stället för att börja med frågan “vilket bibliotek ska ersätta detta?” skulle man kunna gå igenom fyra steg. Ju längre åt höger vi kommer, desto mer specialiserad semantik väljer vi att låta någon annan äga. Ordningen är ingen sanning – mest ett sätt att göra valet medvetet.&lt;/p&gt;
    &lt;div class=&quot;flow&quot;&gt;
      &lt;div class=&quot;step&quot;&gt;&lt;b&gt;1. Behövs det?&lt;/b&gt;&lt;span&gt;Behövs beteendet över huvud taget? En cache eller intern event-bus som aldrig byggs har ingen implementation att förvalta.&lt;/span&gt;&lt;span class=&quot;arrow&quot;&gt;→&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;step&quot;&gt;&lt;b&gt;2. Finns det i JDK?&lt;/b&gt;&lt;span&gt;Finns en direkt och tillräcklig lösning i Java 25? Till exempel HTTP-klient, filer, Base64, scheduling.&lt;/span&gt;&lt;span class=&quot;arrow&quot;&gt;→&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;step&quot;&gt;&lt;b&gt;3. Räcker lite egen kod?&lt;/b&gt;&lt;span&gt;Är semantiken enkel och lokal? Mappning, konfiguration, en liten retry-loop eller en composition root kan bli ganska tydlig vanlig Java.&lt;/span&gt;&lt;span class=&quot;arrow&quot;&gt;→&lt;/span&gt;&lt;/div&gt;
      &lt;div class=&quot;step&quot;&gt;&lt;b&gt;4. Låt specialisten ta det&lt;/b&gt;&lt;span&gt;Handlar det om JSON, OAuth/OIDC, anslutningspool, brokerprotokoll eller avancerad telemetry? Då tror jag ett moget bibliotek nästan alltid är billigare.&lt;/span&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;
  &lt;section class=&quot;section&quot;&gt;
    &lt;p class=&quot;eyebrow&quot;&gt;04 · Var Spring kanske passar bäst&lt;/p&gt;
    &lt;h2&gt;Tänk om Spring fick bo vid kanten?&lt;/h2&gt;
    &lt;p class=&quot;copy&quot;&gt;Den idé jag själv tycker är mest intressant handlar inte om att ta bort Spring Boot. Den handlar om att kanske sluta låta Spring vara applikationens huvudsakliga programmeringsmodell.&lt;/p&gt;
    &lt;div class=&quot;arch&quot; role=&quot;img&quot; aria-label=&quot;Arkitekturdiagram: omvärld går via Spring vid kanten till en kärna i vanlig Java och sedan via adapters till externa system.&quot;&gt;
      &lt;div class=&quot;arch-grid&quot;&gt;
        &lt;div class=&quot;arch-node&quot;&gt;&lt;div class=&quot;arch-label&quot;&gt;Omvärld&lt;/div&gt;&lt;div class=&quot;arch-title&quot;&gt;HTTP · identitet · drift&lt;/div&gt;&lt;div class=&quot;arch-copy&quot;&gt;Protokoll, routing, säkerhet och standardiserad observability är komplext och förändras över tid.&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;arch-node edge&quot;&gt;&lt;div class=&quot;arch-label&quot;&gt;Kanten&lt;/div&gt;&lt;div class=&quot;arch-title&quot;&gt;Spring när det hjälper&lt;/div&gt;&lt;div class=&quot;arch-copy&quot;&gt;WebMVC, Security, adapters och bootstrap. Ramverket översätter till applikationens egna typer.&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;arch-node core&quot;&gt;&lt;div class=&quot;arch-label&quot;&gt;Kärnan&lt;/div&gt;&lt;div class=&quot;arch-title&quot;&gt;Vanlig Java&lt;/div&gt;&lt;div class=&quot;arch-copy&quot;&gt;Domän, use cases, records, konstruktorer, invariants och små portar utan Spring-typer.&lt;/div&gt;&lt;/div&gt;
        &lt;div class=&quot;arch-node ext&quot;&gt;&lt;div class=&quot;arch-label&quot;&gt;Gränser&lt;/div&gt;&lt;div class=&quot;arch-title&quot;&gt;Små adapters&lt;/div&gt;&lt;div class=&quot;arch-copy&quot;&gt;JDBC, JSON, externa API:er och köer kapslas bakom tydliga interfaces.&lt;/div&gt;&lt;/div&gt;
      &lt;/div&gt;
    &lt;/div&gt;
    &lt;p class=&quot;copy&quot; style=&quot;margin-top:24px&quot;&gt;Min tanke är att om kärnan är fri från Spring blir nästa beslut mindre dramatiskt. En komplex tjänst kan lugnt stanna på avskalat Boot. En liten intern tjänst skulle senare kunna gå längre mot ren JDK. En batch eller worker behövde kanske aldrig Spring från början. Men det är just en tanke – jag vet inte hur väl den håller i era system.&lt;/p&gt;
  &lt;/section&gt;
  &lt;section class=&quot;section&quot;&gt;
    &lt;p class=&quot;eyebrow&quot;&gt;05 · Några saker jag är nyfiken på&lt;/p&gt;
    &lt;h2&gt;Allt behöver nog inte behandlas lika&lt;/h2&gt;
    &lt;div class=&quot;cards&quot;&gt;
      &lt;div class=&quot;card&quot;&gt;&lt;span class=&quot;tag remove&quot;&gt;Kanske enklare idag&lt;/span&gt;&lt;h3&gt;Lombok och mappare&lt;/h3&gt;&lt;p&gt;Records och explicit kod gör att en del av den mekaniska hjälpen känns mindre värdefull än den gjorde tidigare.&lt;/p&gt;&lt;/div&gt;
      &lt;div class=&quot;card&quot;&gt;&lt;span class=&quot;tag remove&quot;&gt;JDK räcker ofta&lt;/span&gt;&lt;h3&gt;Utgående HTTP&lt;/h3&gt;&lt;p&gt;JDK HttpClient verkar räcka långt för vanlig service-to-service-kommunikation.&lt;/p&gt;&lt;/div&gt;
      &lt;div class=&quot;card&quot;&gt;&lt;span class=&quot;tag assess&quot;&gt;Beror på tjänsten&lt;/span&gt;&lt;h3&gt;Spring DI&lt;/h3&gt;&lt;p&gt;Konstruktorinjektion behöver ingen container. Samtidigt kan en stor och dynamisk objektgraf mycket väl motivera Spring.&lt;/p&gt;&lt;/div&gt;
      &lt;div class=&quot;card&quot;&gt;&lt;span class=&quot;tag assess&quot;&gt;Värt att titta på&lt;/span&gt;&lt;h3&gt;JPA / Hibernate&lt;/h3&gt;&lt;p&gt;För tydlig SQL och en begränsad modell kan JDBC vara enklare. För rika objektgrafer är ORM antagligen fortfarande billigare.&lt;/p&gt;&lt;/div&gt;
      &lt;div class=&quot;card&quot;&gt;&lt;span class=&quot;tag keep&quot;&gt;Här skulle jag behålla&lt;/span&gt;&lt;h3&gt;JSON och säkerhet&lt;/h3&gt;&lt;p&gt;Generell JSON-parsning och OAuth/OIDC bär på svår semantik som sällan bör bli egen infrastruktur.&lt;/p&gt;&lt;/div&gt;
      &lt;div class=&quot;card&quot;&gt;&lt;span class=&quot;tag keep&quot;&gt;Här skulle jag behålla&lt;/span&gt;&lt;h3&gt;Connection pool&lt;/h3&gt;&lt;p&gt;JDBC finns i JDK, men en produktionsmässig pool gör det inte. HikariCP känns som ett självklart kvarvarande beroende.&lt;/p&gt;&lt;/div&gt;
    &lt;/div&gt;
  &lt;/section&gt;
  &lt;section class=&quot;section&quot;&gt;
    &lt;p class=&quot;eyebrow&quot;&gt;06 · Vad skulle vi vinna?&lt;/p&gt;
    &lt;h2&gt;Om det stämmer handlar det om förvaltningskostnad&lt;/h2&gt;
    &lt;p class=&quot;copy&quot;&gt;Det som skulle göra idén värd något är inte ett snyggare dependency tree. Det är om teamet över flera år får mindre teknik att koordinera, färre lager att förstå och mindre påverkan när plattformen uppgraderas. Och det är förstås ett antagande som behöver prövas.&lt;/p&gt;
    &lt;div class=&quot;table-wrap&quot;&gt;&lt;table&gt;
      &lt;thead&gt;&lt;tr&gt;&lt;th&gt;Om vi minskar…&lt;/th&gt;&lt;th&gt;Skulle vi kanske få…&lt;/th&gt;&lt;th&gt;Men bara om…&lt;/th&gt;&lt;/tr&gt;&lt;/thead&gt;
      &lt;tbody&gt;
        &lt;tr&gt;&lt;td&gt;Externa dependency families&lt;/td&gt;&lt;td&gt;Färre separata versions- och uppgraderingsspår&lt;/td&gt;&lt;td&gt;Vi inte ersätter dem med stora interna ramverk&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;td&gt;Spring-typer i domänen&lt;/td&gt;&lt;td&gt;Mindre påverkan av ramverksuppgraderingar och enklare tester&lt;/td&gt;&lt;td&gt;Gränserna mellan kärna och adapters är tydliga&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;td&gt;Runtime-magi&lt;/td&gt;&lt;td&gt;Synligare kontrollflöde och enklare felsökning&lt;/td&gt;&lt;td&gt;Den explicita koden förblir liten och begriplig&lt;/td&gt;&lt;/tr&gt;
        &lt;tr&gt;&lt;td&gt;Överdriven standardisering i kod&lt;/td&gt;&lt;td&gt;Mindre lokal infrastruktur&lt;/td&gt;&lt;td&gt;Organisationen fortfarande standardiserar viktiga kontrakt och driftbeteenden&lt;/td&gt;&lt;/tr&gt;
      &lt;/tbody&gt;
    &lt;/table&gt;&lt;/div&gt;
  &lt;/section&gt;
  &lt;section class=&quot;section callout big&quot;&gt;
    &lt;p class=&quot;eyebrow&quot;&gt;07 · En sak som kan ha ändrats&lt;/p&gt;
    &lt;h2&gt;Mer kod kan ibland betyda mindre system&lt;/h2&gt;
    &lt;p&gt;AI gör det billigare att skapa mekaniska mappare, JDBC row-mappers, config records, adapters, tester och repetitiva decorators. Om det stämmer minskar värdet av abstraktioner vars viktigaste bidrag är att vi slipper skriva några rader.&lt;/p&gt;
    &lt;p&gt;Samtidigt gör AI knappast protokoll, kryptografi, parsergränsfall, concurrency eller transaktionssemantik mindre farliga. Det går snabbt att generera en anslutningspool. Det betyder inte att teamet borde äga en.&lt;/p&gt;
    &lt;div class=&quot;rule&quot;&gt;Lite mer &lt;em&gt;synlig kod&lt;/em&gt; skulle kunna ge ett betydligt mindre system.&lt;/div&gt;
  &lt;/section&gt;
  &lt;section class=&quot;section&quot;&gt;
    &lt;p class=&quot;eyebrow&quot;&gt;08 · Så här långt har jag kommit&lt;/p&gt;
    &lt;h2&gt;Kanske handlar minimalism mest om att välja ansvar&lt;/h2&gt;
    &lt;p class=&quot;copy&quot;&gt;Jag ser ingen poäng i att göra “noll Spring” till en trosbekännelse. Däremot tror jag att det finns något i att göra varje dependency medveten.&lt;/p&gt;
    &lt;p class=&quot;copy&quot;&gt;En liten tjänst skulle kanske klara sig på JDK:s HTTP-server. En komplex publik tjänst kan gott stanna på WebMVC och Spring Security. En worker kan kanske vara nästan ren Java. Det gemensamma vore att affärslogiken får vara vanlig Java och att specialistbibliotek hålls vid tydliga gränser.&lt;/p&gt;
    &lt;div class=&quot;quote&quot;&gt;Fråga först om det behövs. Titta sedan i JDK. Skriv liten, konkret kod när semantiken är er egen. Och låt specialistbiblioteken ta det som tillhör ett svårt protokoll, en säkerhetsstandard eller en resursmanager.&lt;/div&gt;
    &lt;div class=&quot;note&quot;&gt;&lt;strong&gt;Det här är en idé jag gärna vill tänka vidare på tillsammans med andra – inget migrationsrecept.&lt;/strong&gt; Jag är fullt beredd på att den håller sämre i verkligheten än på pappret. Frågan jag tycker är intressant är inte “kan vi ta bort Spring?”, utan “vilken teknik ger faktiskt lägst total ägarbörda för just den här tjänsten?” Har du erfarenheter som pekar åt ett annat håll vill jag gärna höra dem.&lt;/div&gt;
  &lt;/section&gt;</content>
  </entry>
</feed>
