Spring I/O

Spring I/O 2026 Keynote

1:08:44 · 13 Apr 2026 – 15 Apr 2026 · YouTube

About this talk

This talk focuses on the new features and advancements in the Spring Framework 7 generation, emphasizing its baseline with JDK 17 and recommendations for using JDK 25. The speaker highlights enhancements in performance, concurrency, and programming model, especially the support for virtual threads introduced in Project Loom. The session also discusses the integration of Kotlin 2, JUnit 6, and new capabilities like structured concurrency and null safety. Moreover, it delves into the Spring Module project aimed at structured application architecture and improved testing mechanisms for modular monoliths. Key updates regarding dependency management and observability features are outlined, positioning Spring as a robust foundation for modern cloud-native applications.

Full transcript

I guess I Yeah, I'm I'm all set. So, uh, welcome welcome from my side. Um, glad to see you all in here in this packed room. And I can actually see you even better um because the lights are just fine. Um so I uh once again have the opportunity and the pleasure to do the introduction for this keynote just for a couple of minutes before we dive

into specific topics a little more deeply. Um connecting to just uh what you've heard from from SI uh we have great attendance here from all over the the the globe in the meantime which is uh uh amazing. But uh a particular call out to my fellow Austrians. We're number three now in the attendance list, right? So, one one up from last year. So, um um yeah, um

that there's that. Let's uh move on to um um the topics of this morning. So, what am I actually introducing here? Well, uh sort of the keynote obviously um but it is in particular about a new generation of uh spring framework itself and the entire portfolio that builds on top of it. So this is the spring framework 7 generation and please do note that the generation is

still in the traditional sense of a a major release generation that lasts for a number of years. We still we we think along generational lines as we plan for um uh the releases um that that we have in mind for the next couple of years. The spring framework 7 generation has been kicked off with the 7.0 release and we're working towards 7.1 from here. Now in spring

framework 7 and this applies to the entire generation. We actually have a bit of a a uh almost conservative choice in there. We keep using JDK17 as our Java baseline. This is in in alignment with uh the wider industry. There's basically industry consensus around JDK 17 in many areas. Um so we chose not to uh raise that baseline which is a bit unusual since we usually do

this for major releases. However, this really goes together with uh embracing the very latest JDK generations out there. The baseline may be at Java 17, but we highly recommend using JDK25 from where we are right now. And within the planning of our generation, there's already JDK 29 as the next long-term support generation of Java uh on the horizon. It's going to come our way September next year.

This is not far out. This is uh within our planning horizon of the spring framework 7 generation. So we are we are embracing JDK25 right now and we are up for embracing all the goodness that JDK29 will give us um by late next year. This in particular applies to two specific areas or two specific projects as they call it in Open JDK areas of improvement. um project

Leiden the AOT cache feature in uh in Open JDK really went a long way toward JDK25 already. So what you can consume right now in JDK25 is already much much more capable than uh the class data sharing feature that that that came before there but it's not at the end of its evolution yet. There's a couple of uh further improvements uh um like full code caching, a

couple of other things coming coming up just over the next couple of Java releases definitely going or well highly likely to be in by JDK29 um the next LTS release. So, embrace project light and embrace the AOT cache right now and you're set up for consuming the improved version, the enhanced version of the AOT cache um in JDK 29 next year. Project Bloom, the other project that

we are full uh that we are so heavily embracing is uh about virtual threads. Virtual threads have may have been introduced in JDK 21 but they really came together in JDK 25 24 25. What you get right now as a virtual threads arrangement in open JDK is already a much improved version um without much of the pinning deadlocking problems that may have appeared before. We strongly recommend

um exploring the goodness that virtual threats can bring to your systems. Now against GDK25, skip 21, go straight to 25. There's further improvements along the way. So structure concurrency sixth preview. It's still not out of preview. Uh it's also part of project bloom building on top of the core virtual thread foundation. And we're very interested in doing the best we can to be uh the best possible

citizen in in structure concurrency programming along those lines as well. This is likely to materialize in open JDK within our spring framework 7 generation. So within basically the next two years within the design phase of the spring framework 7 So much for the Java baseline and uh remember JDK 17 a rather uh conservative baseline there. there is a much more aggressive baseline, a brand new baseline in

other areas. Uh we are fully embracing cotling 2 and we use cotlin 2.2 as our minimum now for cotlin uh development and uh uh well uh there's a dedicated session here um um at uh at spring.io about using cotlin with spring so I won't go into it too much here. Um we are embracing Gravian25 in the new metadata format in the spring 7 spring boot 4 generation.

We are um embracing JUnit 6 which is the first major release of JUnit uh the testing framework uh in in a long long while right so uh uh these are key key updates available out there in the ecosystem that we're fully embracing in spring fun 7. the uh umbrella the Jakarta E11 umbrella uh that uh delivered a couple of very interesting upgrades um that we also embracing

here in Spring 7 server 6.1 JPA 3.2 too bean validation as well. Of course, uh this is less about the APIs, more about the providers. It is about being able to fully embrace Tomkit 11, the JD2.1 generation and in particular hibernate or M7. So, uh spring framework 7 is also the opportunity to bring hibernate 7 and uh basically all the latest from the ecosystem into your right

into your hands. This is also a minimum. So uh uh we intend to embrace the further evolution of hibernate tomkit from here within the spring framework 7 generation. Um Jakarti E1 essentially is uh the Last but not least 3. Um the first major release of Jex in at least 15 years. Um, this exists side by side with Jackson 2 support, but keep in mind the Jackson 3

is really a rare opportunity uh also for the wider Jackson ecosystem to rebase itself uh onto a redesigned modern-day version of Jackson. Um, so Spring 5X 7, Spring Boot 4 come with everything required uh for you to to be able to upgrade to Jackson 3 right away or to uh define your upgrade path toward check 3 over um the next year or two. J specify gave us

a new way to define nullability null safety in our code bases. We are fully embracing chase specifiers, type level annotations in uh not only springback 7 itself but in the in the wider spring portfolio on top of springback 7, spring boot 4 and so forth. This is basically a revisiting because we had our own nullability annotations before which we are replacing with ch specify now um also

in alignment with the wider ecosystem. Um indeed the power of being able to express nullability in more fine grained ways within generics uh and so forth is is really absolutely worth it. Not least of it all the tooling support null and others. Um the support intelligj for example 4J specify is just awesome. Uh I personally would not want to miss this. This is a for us it's

uh it uh saving so much trouble to be able to cleanly define nullability in the entire framework the API and the implementation. I highly recommend exploring what this can do to your application code bases as well. Um quick note that we have a new mechanism for programmatically registering beans uh as an sort of alternative to um the at bean methods uh factory methods that you are used

to. Um it's called bean register. Um there's uh uh no time to go into the details. It's also in combination with that configuration class is usable for certain uh uh specific needs where you need a more dynamic way of registering a number of beans. Uh so there's structural flexibility in programmatically expressing your your your bean registrations over statically declaring methods. That's also a spring from 7 theme

that we keep uh uh improving on from 70 to 7.1. the core resilience features. What we mean by that is uh that we brought uh core retry support and concurrency limiting into the core framework. So there's new facilities available in spring framework itself uh for um programmatically retrying but also for declaratively uh annotating methods in order to be retryable. I have a dedicated breakout session on this

this afternoon. API versioning is also a uh pretty major revisiting of our web endpoint model. We have first class support for expressing version arrangements in our web endpoints. The uh versioning strategy is centrally configurable but the the expressiveness of attaching yourself to the versioning scheme is right there in the mapping annotations for your web endpoints. also a pretty it's it's basically industry standard conventions that you can

uh align with in your application arrangements but the framework gives you centralized and built in facilities for um centrally defining this for your applications. Last but not least, uh other areas, there's plent there's more. The the one that I uh have left for you here is GMS client, which in itself is the completion of a bit of a longer work stream where we introduced REST client. We

introduced JDBC client which again built on former uh the web client, the database client in ArtoDBC. There's there's quite a few client APIs. This is basically our modern-day API design for programmatic client interactions. Um, so JMSs client is sort of a uh a convenient facade for for JMSs client access instead of using JMSs template uh or JMSs messaging template. Specifically, if you're familiar with JDBC client or

restclient already, you'll find yourself um familiar with JMSs client as well. If you look at it, this is all available in spring framework 7.0 already since November and it's the foundation for the current spring boot 4.0 generation and for the immediately upcoming spring boot 4.1 generation which is due in May. We are already working toward the next core framework revision spring framework 7.1. a reminder that comes

up in November uh and November 2026 going to be the foundation for spring boot 4.2 two um and for the three following and uh we keep having a focus on the aforementioned project lighten and project loom and this is where we are going to dive a little deeper on Rosson the stage is yours. Thank you. Good morning and a warm welcome from me. When it comes to

concurrency, asynchronous code um and scale in Java, we've been through many phases. Um and I would like to take a brief um amount of time to reflect on where we've been, where we're going, um and and how we got here even in the first place. Concurrency is a strength of Java. From the very first version, we've been able to we've had synchronization and multi-threading and the ability

to run multiple threads in a single process. Um, which was a big deal back at the time. And over time, we got improvements. Uh, so for example, in Java 5, we got the Java concurrency util package uh with all the goodness in that. Uh, by Java 8, we had the fork joint pool and the completable future. Um and all of this created a sort of fine balance

um across applications um because for the most part at at the time applications you know were serlet applications controllers could run in their own thread. They didn't really have to worry too much about concurrency and synchronization and all the hard work was actually done in servers and libraries underneath. Um so I think that the tools and the capabilities provided by the language were um um a a

good fit for things at the time and that all came to um there was a quite a disruptive moment in the early 2010s with the adoption of microser architecture at which point um it became very common for controllers to call out to other services and all of a sudden for the first time we had concurrency in application code in a way that we had not seen before.

And this meant that we have um a rise of complexity first of all in order to deal with all of that. And secondly, because this is happening on the server side, you have an explosion in the number of threads and rise in the cost um and very quickly the limit of scale. Anybody remember the 10 CK um test? It was in this context, someone does. Um it

was in this context that the reactive stack was born. Um and at that point we um already had um Node.js popularizing the event loop and demonstrating that you can scale with a very small number of threads and in fact with a single thread without blocking. Uh we had the reactive X style functional programming um to express logic which allows you to be neutral to asynchronicity. And of

course we had the reactive stream specification which was um the ability for components from different providers to uh communicate with non-blocking back pressure. Um and on that foundation uh in 2015 17 with spring framework 5 uh we had the web flux project. Now over the past 10 years um um the web flux was adopted um fairly widely because um with the reactive stack we had the tools

necessary to solve the problems within the application space. um applications were able to scale with a small number of threads and also they were able to express logic in a way that is much better than um callbacks, nested callbacks and the um callback hell that um was well known at the time. Um at the same time there were barriers um to adoption um because you know there's

a learning curve and also at runtime you're still exposed to um and all of this means that um the reactive stack um gave us uh the tools um but also um it um normalized quite a number of things that over the past years 10 years we've come to expect. Um we're talking about things to do with concurrency um and streaming using the reactor flux uh that provides

capabilities that we're now accustomed to and and we pretty much expect to be able to do. Sometime after that um we had project loom um a result of many years deliver virtual threads and this is um something that fundamentally changed the equation because suddenly blocking is no longer expensive. Um it removes uh the need to avoid blocking and that means that you can write applications in imperative

style. Um and this is a very big fundamental shift that that changes everything in terms of the way we think about um the problem and in a way that only um can be solved at the JDK level. So all of this means that today there is a renewed focus on being on a blocking stack. Um now historically when we created Web Flux that's a completely separate stack

from Spring MVC. So we've always had Spring MVC and Web Flux side by side. Um, and this is a great place to be um, because with Spring MVC, your existing applications can take advantage of Project Loom in many cases without even the need for any changes. Um, Spring MVC through all these years remained the sort of the premier um, webstack, the one that's used um, most widely

and we never really look to uh, demote it in any way. And if we look on a timeline, um currently um Spring Framework 7 covers from Java 17 and forward compatible to Java 25. Uh that gives you the full ability to run with Loom and virtual threads. Um and also with Java 24 uh Loom without pinning. In fact, we recommend Java 25 for production. Um so virtual

threads give us the scale. So we can block and we can have many threads but we still need the concurrency within controllers in order to be able to make those remote calls. And that is something that structured concurrency is going to deliver. Um and it's currently in six preview. Um and we expect that within the spring framework um 7 um generation um we we will see that

um in in a Java version out of preview. And beyond structured concurrency, uh there is another topic which is very important. Um and I mentioned earlier the reactor flux and that is the topic of data streaming. Um and the reason why this is very important is because there is another disruptive change happening today. Um just like in the early 2000s microservices brought concurrency into application code, today

AI is bringing streaming into application code in a way that we have not really seen before. Uh web streaming is of course not anything new. Um I'm sure many of you here have already done it in applications. Um but we're talking about something which is very very now much a requirement a prerequisite for doing something that a lot of applications a lot of companies need to do.

Um and and that is really what's different. Now this goes way beyond Java. Uh there's actually a lot of experimentation happening in the MCP protocol uh to find ways to do streaming to do two-way communication between clients and servers. Um I think the protocols of today are not quite there yet. Um so there's a lot of work happening even way beyond Java. So if we think a

little bit about what does it mean to support data streaming on a Loom stack? Well, this may not be an obvious challenge at first um because historically we're used to having a callback interface and um you have on data on next um on complete on error and and you receive those notifications. But uh with Loom the expectations and the the mindset is changed in that we expect

to have an imperative um style. So an iterator style of consuming a stream is preferable. for example. Um but once we move to that kind of contract there's a lot of questions that begin to come up um about life cycle um about resource management um about cancellation um and um how this is to be used um so we essentially need the equivalent of the reactive streams contract

uh for loom for the loom stack and if we think about consuming a stream there's also the reverse side which is producing a stream and if we think about both of those symmetrical then it's something that begins to look like a channel. Um and then we can talk about independent consumer and producer and all of that brings up even more questions and issues that need to be

solved. Um today the structured concurrency specification mentions explicitly channels as a known goal. Um but we know that this is something which is coming to Java eventually. In the meantime, we're looking um very um we're doing very actively research into this space. Um and for Spring Framework 7th generation, we want to provide some way of um allowing um streaming in a loom friendly fashion. Um probably most

obviously starting with a REST client where you might want to consume for example a serverent event stream instead of through an input stream and parsing it um as a stream of higher level objects. So those are the kinds of things that we want to uh begin to expose. And of course the uh use of this goes way beyond the rest client. Um there is AI, there's MCP

um and and there are countless examples of a producer consumer scenario uh through many um areas um in the application Um, another area in which we're focusing uh for Loom applications is performance optimizations um in Spring MC. In addition to uh using leaden to generally improve um things, we're also looking um very closely at performance and we're optimizing we're running benchmarks and we're identifying bottlenecks and then

we're finding places uh for improvement. So what you see here um is um performance tests um from the sixth generation and the seven uh do um versions. Um the 61 is on Java 21. Uh the 70 is on Java 25. And you can see there is an incremental improvement from uh version 6.1 uh the latest to 7.0.1 um and that is a 5% improvement. Um whereas from

7.11 to 706 there is a uh 21% improvement and and those are the kinds of things that we uh find if we can roll them into the current production release. If we think it's safe enough then we do that and you can see the result here um on the x line down there by the way is the amount of data and then the throughput is on the

y line. Um so those are things that we're very actively pursuing and um we are continuing on that theme. Uh so some changes are only going to be possible in the next minor release for example 7.1. Uh so you can expect to see more of this but we're very actively looking at um at this space and making improvements. So with this I would like to introduce uh

the next speaker uh Oliver Dropboom. Um and we're going to raise it up a level to architecture concerns. Oliver, >> thank you. Thank you, Rosson. Um, switching gears a little bit because not only is the Spring team taking care of your applications running as performant and as efficiently as possible, but we also uh like to give you some guidance on how to structure applications. And that's what

I'm going to talk about for the next couple of minutes. Imagine our like standard e-commerce application that logically consists of these units here like a catalog, checkout, shipment, usually roughly aligned with your business departments in your company. If you started building this application in sometime the 2019 and you were part of the late majority, you were building this stuff as microservices, right? So that actually means for

each of the individual elements you build a spring boot application and that building a distributed system usually comes with uh some some challenges and there's support in the form of the spring cloud projects um for that. So you would actually distribute configuration you using uh springcloud config server or make sure that you didn't accidentally break any of your uh consumers with spring cloud contract. Now, one year

later, microservices are still the thing, right? But there's a new thing coming up here called a modular monolith. Ironically, there's another thing coming up which is correctly built distributed systems. It's like introducing your customer success department in your company and then what's everyone else doing, right? So, with that, like what's the idea here? So, instead of building individual systems, we built fewer systems. not necessarily one but

fewer systems and still maintain that structure inside of the very system that of course needs some tooling or some help to actually make sure that uh the structure doesn't erode and that's where the spring module project comes into play right and there it's a pretty simple approach then in some test case or what have you uh you use that um application modules type here point it to

your spring boot application class and then call some flavor of verify on it uh to actually make or that uh you didn't make any structural mistakes like cyclic dependencies using field injection. And that innocently looking application modules type here does quite some heavy lifting because it analyzes your application structure, the code as you laid it out in front of us and we can actually reason about the

bigger uh elements, architectural elements in your codebase, but also of the entire thing, right? The entire composition and that allows us to do quite a few interesting things, right? So this structure that you put into your codebase actually becomes a feature for us to to to act on. Right? So let's take a step back. Why do we even want to do this in the first place? Well,

the promise was um like building microser that that is the promise was that we can ship features faster because we can basically focus on a particular problem domain and then um yeah test things individually. That's one thing, right? Um to deploy the thing easier. So we basically single out a part of the system and bring that to execution which is pretty easy in this case because it

just means running the entire application at the same time or at at this point here. How does that work in a in in in a monolithic environment right? So you have a bigger application. How do you single out these individual parts? And to explore that, let's have a look at how you actually structure your codebase and how do you align or assign uh a part of the

codebase or your code to a particular part of the codebase. And spring has a history of actually allowing you to do that in a slightly like different form. But let's say we have this kind of layered architecture thing. It doesn't really matter if it's the web or persistence thing. Could be adapters in hexagonal speak or it could be ring the infrastructuring and onion but framework allows you

to stereotype parts of your codebase for ever since the inception of the annotation based programming model here. Right? So you assign a piece of code to a particular layer of the application and then Spring Boot follows suit to actually make use of that structure of that horizontal structure um to actually allow you to execute or only include these elements of the codebase in uh a test execution

for example right and everything is like horizontally oriented that's why or that the reason for that is that framework of course is interested in providing technical services to your code URI mapping for controllers, resource management and exception translation on the repository level. That said, we want to do something else, right? We want to actually use that vertical structure and with the application modules type actually being avail

or able to uh make that assignment, right? Which piece of um is belonging to the checkout and which piece is belonging to the shipment. We can actually reason about that and we can use that at test execution time with a dedicated annotation. Right? So you can actually single out that vertical slice and run that piece of or that part of your your application individually. Up until version

2.0 even it wasn't possible to combine the two, right? You couldn't basically say run the checkout thing but only the data bits of it um due to some internal implementation details. But with the new release in 2.1, we actually provide you a module slicing annotation that just takes care of the the selection of like which code to execute and then you can basically um even slice and

dice the way you wish. All right, so that allows us like to run individual parts of our application as part of integration tests or a single one which begs the next question like what if we want to actually have a bigger integration test? So basically make sure if we check out an order the inventory gets updated. And if you think about that in a microservices arrangement that

becomes non-trivial in the first place because you need to run that other thing. You need to make sure it behaves the way you want it to behave in your test case. Um so there's quite a bit of ceremony involved. Not even to mention like all the infrastructure, Docker containers, test containers, what have you. In a monolithic scenario, it's a bit easier because as I said, we have

access to the individual parts, but we also have access to the to the uh overall arrangement. So, we with this scenario API we provide you, you can just include additional modules in the test run uh inject this scenario type into your test case and then use a pretty readable as I think uh API to do this given when then thing by stimulating the arrangement that you bootstrapped.

Right? So we trigger the checkout here and then we just wait for something to happen eventually right the in basically the inventory updated event referring uh referencing the order that we initially created. um it takes care of all the potential synchronous and asynchronous interactions in the back. There's a weight utility um used here, but it's becoming pretty easy to just select the scope or yeah basically find

the use the right scope of integration test that you think is reasonable for a particular test case scenario given the that flexibility. Uh or let me start it the other way around. be reminded we we didn't start this thing because we wanted to run fancy tests. We wanted to deploy faster, right? So now that we have like a ton of integration tests, uh we might be want

to be selective about the tests that we actually run. Um and given a change that we can like find in your application, let's say you locally changed only classes in module A, which tests do we need to run? the ones for A. Right? So that's that's pretty pretty easy and straightforward and would sim um similarly translate into the microservices world. If we detect a change in C,

which tests do we have to run? >> C and A, right? Like but in a stock standard like separate systems environment, you probably run the tests for C. But then also running the tests for A requires again quite a bit of like downstream setup, analysis, uh CI pipelines being set up, what have you. um with the application modules type as part of the spring module testing support

we actually can reason about the entire thing in the first place uh when executing your JUnit test. So there's an additional jar that you put on your class path that hooks into the JUnit uh test detection cycle and we can basically we we look at the the delta or the the changes that you made to your to your codebase and then basically decide which which tests to

run. So you get that out of the box and hopefully deploy faster. That's the developmental side of the story. Once you run the application and you run microservices, you usually have those services interact with each other, right? So it's either HTTP calls, GPC calls, GraphQL calls, or message-based interaction. and to keep track of who calls whom. Um or the same the same thing applies to to a

moduleic environment right here. You could also listen to events or invoke spring beans on some foreign module. Uh basically being the equivalent of an HTTP interaction. Um but to actually do that you usually deploy any some kind of um metrics infrastructure and tracing infrastructure. What you see here is not a preconfigured dashboard or something, but the thing that you get out of the box if you enable

the modu the observability features um within modul. It's basically creating counters for all the application level events that you publish which you could then basically configure alerts on basically saying if my order completed rate drops in a given percentage then uh send me an alert or something. But we also um have tracing enabled out of the box. I'm not sure how well visible that is in the

back, but we structure the spans within the trace alongside the module boundaries. Right? You see the request coming in, then the order module triggering or being triggered, then the payment thing being triggered, and here then some engine kicking off some asynchronous processing. It's kind of a next level of uh of detail in your overall trace. So if if that um that request coming in came from another

microservices microser that would um just basically be part of the overall trace right. Um not only does or can we make use of that information at runtime um the our friends at uh IntelliJ also like in use that structure to present the code base to you in a way that's more aligned with your logical uh structure instead of just like presenting you a source folder packages or

what have you. Right? So in the in the lower um left here you see the logical modules derived from your actual codebase and they even go one step further and uh there's this some kind of um visibility concept here. So they um can actually um show you the the packages in which code is accessible to other modules versus the internals of the order module in this case

that that are unaccessible. Right? Um the spring tools team does a similar thing for VS code and Eclipse by again presenting you the the module structure as the top level decomposition thing and then even going slight step further by trying to discover certain stereotypes that align with your um designed um pattern languages like domain driven design or there's like also technical stuff in here like configuration classes

in spring so that you don't ne need to navigate your um types based on the file system structure. but rather based on the the uh abstractions that you use in your design and um architectural language. There's tons of other stuff uh surrounding that um support for uh documentation being generated uh from your codebase. Um we've uh just introd or going to introduce in in in the May

release modularware database migration. So each module can migrate their their own schema which is kind of nice for tests because then you don't need to initialize the entire database all the time. Uh there's a lot of event- based uh interaction uh support here. But uh yeah, so am I saying we don't need to build microservices anymore? That's actually totally not what I'm saying. For one, I think

and I guess that's a bit of a bold statement, but I think every non new non-trivial application uh spring boot application is supposed to be a spring module application especially because the the the fundamental features are tests only. So it's very non-invasive. Um give it a try. Uh it just makes sure you build like a well structured application. And the even more important bits here is that

whatever architecture style you're choosing, you're well supported from one of the projects available in the spring ecosystem, right? Boot giving you like the support with technical details with dependency selection. Spring module is basically taking care of the the internal structure of your application and of course that application will need to talk to other applications even if it's a intended monolith. Uh and you get great support for

all of these challenges. uh from the Spring Cloud team. And with that, I'm going to hand it over to Christian. Uh and we have a bit of a short laptop change break. Josh, stop twiddling. Very good. Thank you very much. Please bring your hands together for all the speakers that you heard from the spring team. And by by the way, this might be this is Have you

finished? >> I have. >> You have? Okay. Saw someone else turning up. Yeah, sure. Okay, good. You looked panicked. I was like, "Oh, no. This the dancers are going to come back." Uh, by the way, every year that I come Oh, okay. Oh, good. I always thought I was doing okay. They're not actually coming back. It's a confusion reigns everywhere. No, this So, this chap's coming on

stage. Okay. Okay. There we go. I almost I almost sent everyone out for coffee there. There was just a bit of a pause, but we're we're set up now. Okay. Super. Just think of this as a little sort of intermission. Maybe some time to do some meditation. You're feeling rested. Give me a cheer if you've got kids. Give me a cheer if Give me a cheer if

they're not in Barcelona. >> Yeah, that's it. Yeah. people people who don't have kids who are here. You think you're having a good time. There are some parents going back to their hotel rooms and just going, "Ah, I'm in heaven." Are you ready now? >> I hope so. Yeah. >> Okay. Well, look, after that brief intermission, we're going to have more amazing spring chat. Give a big

cheer. >> Thank you. Hello everyone. I'm delighted to be able to share the road map for Spring AI, at least what's happening in the near future. Starting with 02.0, we're going to align the Spring AI release. This will be the first proper alignment with the rest of the Spring ecosystem. Baseline is boot 4 um framework 7 Jackson 3 by default. All the default players also no safety

adhere adhering to the Jspec specification uh JS specified def. So this also provides support for cotlin renewability out of the box for us. Uh starting it's very interesting that over time um the most of the AI models providers started to recognize or the viability of the Java into the AI ecosystem and as a result we have now native Java SDKs provided for most of the major providers.

When we started with Spring AI a couple of years back that was not the case. we had to build a whole stack and now we use the 20 uh release as an opportunity to refine our implementation of top on top of those new Java SDKs. I have to cow out and thanks to Julian Deua from Microsoft for contributing the open AI SDK as well our friends from

Google Dan Doin which contributed the Google gen AI part. Furthermore, one of the philosophy of the spring AI has been to provide a portable uh API across various AI models. At the same time, by design, we always thrive to provide uh support for native features supported by single models and uh features like prompt caching, batching, structured output. For example, in the case of structure at output, Spring

would allow you to would allow you to opt for the native capabilities of the model if available otherwise it is going to be fall back to the generic SpringKI specification. We put a lot of effort to refine our chat client high level APIs. For example, we realized that the tool calling which is a key abstraction in the AI space in general. The tool calling was built too

low in our stack preventing us from implementing very important uh uh agentic patterns. As a result, we bring now the two co-advisor as our first and preferred way to perform the copiling p uh calling patterns on the chat client level. uh as a result one of the most important and most interesting uh uh opportunity this give us is to implement tools like two search tools if you're

familiar with this you allow you to uh reduce the amount of tools it is practically progressive tool disclosure or allows the to code the tool demands rather than uh throw all tools up front and this kind of reduce a lot of tokens for you if you use MCP for example with a lot of tools a lot of efforts have been put to improve our low layers I

really have to thanks our team Sebastian and Eric Elias soie for putting this effort. This would allow us to really speed up and uh run with the speed of AI which is very important. Um as you may know we have been supporting the official Java Java MCP SDK along Spring AI and uh running starting with 20 we have decided to migrate the MCP transport spring MCP transport

from the SDK into the core same at the same time also graduated the MCP annotations into corso. Now Spring AI is natively MCP supporting everything without needing any additional external dependencies. In general, the MCP Java SDK is very successful project, very popular one and I just dropped this uh recent benchmark I found online which again signified how good Java in GDK is performing in the AI space

in first place. U thanks to the great effort of Darius and uh uh Daniel, we managed to qual uh the cover the tier two. This is a new tiering system that MCP foundation introduced. We're aiming at tier one very soon and with 20 targeting uh GA along the springi 20 later this uh uh next month practically we're going to support uh the latest 2025 specification of MC

uh Java MCP SDK and um this has been only one part of our work most of the innovations we realized early on that the AI needs its own state of evolving so around this time last year We started a project called Spring AI community GitHub organizations. Uh great effort by Mike Pollock um supporting this effort. So we started with like three projects over time now we have

27 and just to name some we have a new session API which is an attempt to which is a new rethinking about how we support short-term memory with Springki. This should graduate in version 21. We have a very successful collection of uh extensible user and agent utils. You can find there aentics agentic skills sub agent auto memory all these very useful things that you can use in

your spring application. Today we have initial implementation of the AI inte uh A2A Google A2A integrations. Thanks to uh Daniel, we have first great enterprise support for the MCP O2 a security specification based on built on top of spring security. Great work. Um we have couple of models supported by the community and uh owned by community. this very another very interesting uh cap uh opportunity with the

SpringKI community project itself and our friends for AWS just to list another important project have provided a great uh integration for the agent core with spring AI and last week or this week they released the version one of their project congrats to Max Andre and the rest of the team you can find many more projects in in in the Springki community or if you have ideas you're

welcome to come here and contribute to Springki This gives me the now let's move forward looking forward I also already mentioned that we have exciting excellent building blocks for building aic application starting with chat client advisor tool calling this helps you to build memory rack advanced track everything you you may want to to build on top of your and build a very sophisticated AI applications but we

still lack a high level agentic abstraction or if you need some sort of durable orchestration uh workflow orchestration uh uh you likely you would have to build it and yourself and put a lot of custom um a lot of custom uh plumbing to do this. So the purpose of version 21 targeted November 2026 later this year. Very ambitious and very challenging and exciting project is to introduce

new spring AI agent agent model with proper high level abstractions stepping on top of what we have right today like chat client with appropriate annotations and programming API models and initial integration with some wellestablished workflow engines. temporal and dapper comes to mind as some of the candidates there. the session API uh is going to be graduated around that time and uh in addition to the completion APIs

which is the common practice today with for integrating with AI models we're going to introduce integration for this new breed called stateful AI API such as response and interaction APIs and looking forward um with Rosen presented very interesting new development of spring framework we would aim to integrate this and provide virtual thread friendly unified streaming API for Spring AI both for SpringKI and the MCP which would

allow us to unify the currently separate reactive and imperative models programming models this support there and with this I would like to hand uh the talk to to Josh who is going to show you how spring actually looks in code and in spirit as well thank Thank you. We have couple of deep dive session today and tomorrow. So please attend if you want to find more about

the details. There's too many too many things to share in a single slide with few few minutes of slides. Okay question. Thanks man. >> Well done buddy. Well done. You want to get a selfie with me? >> Of course. >> Okay everybody pretend like you're happy. We're going to take a quick selfie. Okay. Do you accept my GDPR cookies, >> everybody? >> Let's get the the the

general diagram as >> Oh, yeah. Let's Oh, yes. That's >> Let's get the audience. Here we go. Okay. Uno, do spring Thank you, everybody. Thank you. Good. Good job, buddy. Well done. Hi, everybody. Good morning. How you doing? Don't all answer at once. Go ahead. Uh oh, look at this. Look at this wonderful audience typing on a new laptop here. There we go. Close this out. Goodbye.

All right. All right, everybody. Look, I am of the opinion uh that there's never been a better time to be a JVM and Spring developer. Never ever ever in the history of our ecosystem has there been a better time to be doing what we're doing. And I want to just make that case to you today. I think that we're in an amazing moment in time, right? Just

an amazing moment in time. Um and uh we are in I think we're best positioned of all the ecosystems out there. I think we have an amazing opportunity here. So I wanted to talk about that and of course I'm going to you know I'm going to build some software uh and so on but I want to just talk about this moment that we're in and I'm convinced

that we have an amazing opportunity because we're using JVM and because we're using Spring and you can see this in a lot of sort of anecdotal things right out there. There's a study that just came out. I don't know if you saw this study uh where they looked at uh why AI projects fail and they said something like 95% of AI projects fail. Did anybody of you

any of you see this thing? 95%. That's an incredible number. 95%. If you if if I told you to do something and 95% there's a 95% chance it didn't work, would you do it? Probably not, right? But there's good news. The reason it fails uh is because the integrations are uh and and by the way I feel I feel a little assaulted here. Okay, but but nonetheless

there's a fundamental bit there, right? So the what they're talking about here is they're saying hey these integrations these things that people are building presumably in some other language and some some other ecosystem besides Java and Spring these things are not integrated into the context and into the workflows that people uh uh uh work with every day. They're not part of what they're doing. Right? These applications

are built in different swim lanes than the swim lanes in which people move every day when they do their work in they're not in the same workflows. Okay. Where and how are those workflows built? They're built on the JVM and they're built in Spring. The enterprise runs on this stuff, right? It runs on the JVM and it runs on Spring. The business logic that powers that moves

your organizations forward is in the JVM and it's in Spring. Of course, if you try and build something in Python, it's not going to take advantage of that, is it? It's going to miss that opportunity altogether. We have an amazing opportunity here. We are best positioned to build these integrations. And by the way, there is no reason why we couldn't uh build these integrations, right? the the

technology for building genai applications today with Spring AI is second to none. Not just in the JVM ecosystem. We're talking about all ecosystems. We have an amazing opportunity and we're going to talk about that as well. So, as usual, we're going to build some software. We have to build some software. I want to build something small. We don't have a lot of time. What? Three minutes? That's

not happening. Okay. Yeah. Just got up here. We We have a uh we don't have a lot of time. Uh but we're going to like we're going to build something small, something quick just to demonstrate uh what I'm talking about, right? And so I want to build something very quick here as always. We're going to build I I want to look we have very little time. He

just made that point, right? It's not through any fault of my own, but we have very little time. So I figured we could build uh a secure observable AI agent and MCP system uh uh quickly. What do you think? Okay, so let's do something like that. So we're going to go through here start.spring and I'll build I guess I need authorization. I'll go to start.spr spring and

I'll use off mc mcp. I'm going to build a spring off server and uh this offserver is just an ooth IDP. Okay, not a very big deal at all. I'm going to open that up and I've got some configuration that I'll use to feed that thing. So, I'll copy and paste all this, go to my application.properties, paste all that in there and then in the application code

itself, uh I'm going to click on this. I'll click on setup SDK. Uh please. Yes, thank you. Okay. And by the way, I'm I'm using Intelligj. I love Intelligj. But you might have noticed that I'm going a little slowly. Okay, I'm moving uh I'm moving a No, because I moved LA last year I undertook a spiritual journey. A spiritual journey to learn vim motions. Okay. Right. I'm

I'm learning vim motions. And vim motions allow you to navigate and move quickly. And but but I'm not used to it yet. And this could not have come at a worse time because here I am trying to learn vim motions and I'm hunting and pecking and moving very slowly. This is not how I normally move, right? In fact, last year this wonderful conference at this wonderful conference,

there was a presentation uh here from our friend Anton uh called El Rapido, coding like Josh Long and and I'm not coding like Josh Long anymore, which is awkward. So, so thank you. Um so, anyway, we've got this uh this application and it's just going to be an OOTH IDP. Okay, nothing special here. It's going to be an oath IDP, but it's going to support um you

know, I've got uh the OOTH client here, right? Got that got that defined. I'm pointing to a SQL database. Got virtual threads enabled because I'm a good person. Uh and I'm going to use security filter chain HTTP security. Here we are. Move that there. Security and I'll say MCP authorization server. Okay, this is the Spring AI community about which uh about which uh uh Christian just spoke.

This is a library, an integration that's existing because it's moving quickly, right? And because it's moving quickly, we need to um sort of incubate it elsewhere. Okay? So we can keep up with the uh the ecosystem there. So there's my OOTH authorization server. I need to lock down all requests that go to this authorization server. So I'll say any request is authenticated. Fine. I'll tell it to

support form login. Very good. I'll support the defaults there and I'll support that. I think that's enough. Whatever. And I also want to point it to the SQL database for the users. I've got users in my system, right? Uh not many, but I do have users. So, I'll just integrate that there. Return new JDBC user details manager. Very good. Restart this. Okay, there's my OOTH IDP. Fantastic.

Now, let's go back to the Spring Initializer and we're going to build our next application. Okay, start.spring.io. And here we're going to build an MCP uh service. Okay, and we're going to build an MCP uh client. So, we're going to build a service here. I've got this uh the scheduler. It's just a very simple MCP service. And by the way, we're using MCP, right? Christian alluded to

this. MCP is a protocol for integrating AI models with AI uh uh uh uh um uh services with services that are ready for the AI. And MCP, by the way, is a very very common protocol, but Spring AI is not just as good an option as anything else. As Christian mentioned, we were the ones that built the Java SDK, and it does quite well. How many of

you saw this benchmark here uh just recently? This is a benchmark that came out way back in February. Anybody here remember February? I I I certainly don't. Uh but it came out in February and the results are, I think, uh uh pretty pretty inspiring. So here's um here's a uh an analysis, okay, of the overall performance, right? Look at that. Java has the lowest latency. This is

they're comparing uh Java against three other uh languages. Okay, so you've you've got you've got Go away. You've got this thing and what? So here's Java8 latency, right? And then here's Go slightly behind but still quite impressive. Node an order of magnitude worse and Python almost three orders of magnitude worse. Okay, the number of transactions per request the JVM, Spring AI, Spring Boot and uh the JVM

did the best here, right? The results are quite good uh in all the look at that CPU efficiency for the JVM versus everything else. It's less than a third. Everything else is about a third or 100% in in the in the case of these two choices, right? So again, the JVM is an amazing place to build, okay? It's an amazing place to build MCP integrations. It's not

just a question of like is it as good. It's better. It's already better. It's not a question. Okay, so I'm going to build now an MCP service. Let's go back to the Spring Initializer here. I seem to have hidden all of those options here. Myuler, I'm going to build this using Cotlin. I love Cotlin. Who's who loves Cotlin? Uh such a great language. Okay, so go ahead

and hit generate. It's going to be an MCP service that allows us to answer questions about when we might stop and uh pick up a dog from our fictitious dog adoption agency called Pooch Palace. Not a big deal. Oh, I've already generated this. Uh is it already running? Nope. Here we are. CD uh oh, CD UAO. Here we are. It's a it's just a a service that

we're going to build. And for same thing as before, I'm going to copy and paste the config here. So that's called uhuler. Okay. Gonna set that up in port 8081. It's going to have a simple MCP tool that we can use. I'll just cut and paste that. Here we are. And here we are. Service. Okay. I don't know what that server annotation is, but I wish it

would go away. Here we are. Class scheduleuler service. Look at that fun schedule dog ID int. And we're going to return a Java time.instant. And I know there's a Cotlin version, but whatever. So, here we go. Uh, we're going to return a date. Three days hence. Okay. Three days hence. uh uh uh uh days. Very good. And you know, while we have that, I'm also going to

print out Hey, printing out scheduling uh this dog ID. Okay, scheduling uh dog ID for it. And we're going to have a user. Remember, this is an a sec. This is going to be a secured MCP tool, right? A secured MCP tool. And because it's got a secure uh it's a secure tool, we have access to the context. So, let me put that here. Paste this uh

description for the MCP tool right there. And voila. And we're going to four and then we're just going to get the user like one does. Security context holder.getcontext authentication name. Okay. Now, this is an example of nullability. See that? This is one of the things you saw earlier. This is now a nullable type. This could return null and cotlin respects that natively. So, I'm just going to

yell at it like I do most of my code. Okay, there we go. Fixes it. Always fixes it. Okay, very good. So, there's my MCP tool. I think I'm done with that. I think I've done everything I want. But the point is I have access to the current authenticated user when I make this MCP invocation. Okay, so let's start that up. It'll spin up here. Uh, and

I think we're happy. Now, let's create our agent, the actual thing we're trying to build here. We're going to do this using Java. And again, I'm using Java 25 or later, the latest and greatest LTE version. Java is amazing these days. Okay, it has one of my all-time favorite features ever. Watch this. I'm gonna open this up. Void main. Hello. Ola, print line. Ola, come on. Spring

IO, right? And watch that. Escaping Vim first try. Huh. Amazing. Thank you. Thank you. Thank you. It's hard to do, but I did it. And I'm what I'm going to do is I'm going to pass this Java this program that I've written. I'm going to pass it to Java without compiling it. Okay, kind of like a script. Do you know what you just saw? Do you know

what you just saw? The first good JavaScript. Okay, first one. It's never been done before. Never been done. Okay, and the JVM again, it's just an amazing amazing uh language, right? It's just an amazing language. You probably saw this uh this uh study that looks at the efficiencies of different languages, right? This is from a few years ago. Um, and of course then the results won't surprise

you here. C, most energy efficient for machines, not not people. Rust, well done. C++ tui, disgusting. Moving on. Atta, nobody cares. And then Java, right? 1.98. So top five most energy efficient languages. So again, it's not just fast like we saw with the MCP Menchark. It's also super efficient. And by the way, scroll down the list here. You can see some other options. C is pi. That's

delicious. Okay, you've got go away. You've got these two terrible languages. The less said about which the better. Moving on. And then you've got the sort of the proof of the pudding here, right? C, the Ruby implemented in C is way less efficient than J Ruby, which is Ruby implemented in the JVM, right? And then the thing that's powering all the AI uh nuclear reactors around the

world, how many fewer would we need if we just use something more efficient, huh? So, the JVM is an amazing place to build uh code. So, let's do just that. I've got my uh did I did I generate the zip file? I think I might have. No, I didn't. Start.spring.io. Here we are. And uh we're going to say agent generate UAO uh agent. Okay. And I've got

some config just as before. I'll copy and paste all that. Okay. And uh in this config, oh, there's the agent. Here we are. In the property file, I'll paste all that there. And remember, I've got uh things like my Hello Computer Maven sync. I'm sure this will be fine. Okay. Well, whatever. Um, could this go worse? Let's see. Here we go. Agent code. And all we're going

to do is going to build Oh, there it is. That's the issue. I knew there was an issue somewhere. See, it doesn't want me to use 24. Uh, so I'm going to build a simple controller that answers questions about things about animals in the uh in the in our fictitious dog adoption agency, Pooch Palace. So I'll have an endpoint here called ask and I'm going to say

string ask questions and I'm going to route the questions to the AI model via the Spring AI chat client. Okay, the chat client is your one-stop shop for all your AI integration needs. And it was it was one of my all-time favorite objects. Uh it it was written by the best people. Okay, the actual best people ever, right? So, huge fan, huge fan of the this code.

Now, I'm going to go ahead and uh uh put that there. Thisai.prompt.call.content. I'm going to pass in a user prompt asking a question. Which prompt, you might ask? Well, I've written that down here, too. People don't People think I'm not prepared. It's true. I'm not. So, here we go. I've got this and I'm going to pass in the system prompt here as well. Okay, system prompt. And

take that in here. Paste. Voila. So, I'm going to basically say, "Hey, AI, we are an assistant to help people adopt a dog." And then when and then if people ask for if somebody asks for a date, give them the date using the tools provided, which is the uh remote MCP service that we've wired up in the configuration there. See, you see this configuration down here? We're

saying point to that local host81. We're going to inject that tool here. Default tool callbacks TCP. Uh, and then I'm just going to restart it. Okay, let's see how that works. So, it's going to answer questions on behalf of the user. 12700880. Ask. Okay. I've been redirected to the off server. I'm authenticating. Okay. Log in. Redirect back. Hopefully, there you go. The date is 3 days in

the future. Today is the 14th. This says the 17th. Let's see if that actually worked. Let's see theuler. Did it print it out? There it is. Scheduling for blah blah blah for user Josh. So, now we have secure, aentic, scalable, very efficient, and observable software. Did I mention we have observability going on here? The entire time this has been sending data to Graphfana via the micrometer integration.

Right? So I've got dash sorry drill down and uh metrics and now you've got all this wonderful stuff. So I can I can see for example whether I need to get more funding for my next startup because I've used my tokens. Right? So here's all this stuff. We don't have enough data just yet for it to go there. But you'll see the point is we have now

a very very sophisticated system in no time at all. And that's my point. Technologically, we're already in the pack, in the lead of the pack, okay? This is an amazing moment for us. And there's more to it, though, right? Because I know this is all uh uh this is all roses and it sounds great, but I know you've been hearing some of the um some of the

the depressing news out there, right? And and frankly, I don't think it's that bad. I think actually quite the contrary, I think things are going quite well. First of all, we've discovered a few things about AI. We've discovered that it is um it is good uh for generating code in small contextualized places, right? But in the large it doesn't it doesn't do quite well. And we see

this a we see a natural reaction to this. How many of you have seen this? I think this is a parody. I don't know. I think it's hilarious. A rejection of artificially generated AI slop rags, right? It's a an error code for that. I think that's kind of interesting. Uh and then of course we've seen that people who are trying to embrace AI aren't as productive as

they thought when they let it loose and run on run rampid on code bases without uh without con constraint. Right? So here's a study done last year to be fair uh that looked at well basically let me see uh 19% there you go surprisingly to to nobody we found that developers that use AI tools take 19% longer than without right uh AI makes them slower right so

this is kind of interesting and this is why when I see really hilarious images like I don't know if you've seen these uh these images right have you seen this um these memes right these went viral and they make me laugh because they're they don't seem that seem a little unhinged. How many of you seen this? Tech enthusiasts. My entire house is smart. Tech workers, that's us.

The only piece of technology in my house is a printer, and I keep a gun next to it so I can shoot it. If it makes a noise, I don't recognize, right? Like, if you know how the the the sausage is made, you're not going to you're not going to trust it as much. What about this fake? This is fake. Okay, this is a fake job uh

opening for OpenAI. It's called the kill switch engineer. Listen, we just need somebody to stand by the servers all day and unplug them if this thing turns on us. You you'll receive extensive training on the code word. Uh be patient. Know how to unplug things. Bonus points if you can just throw a bucket of water on the servers, too, just in case. Right? So, there's that. And

then, uh my favorite one is this one, right? Where do you see yourself in five years? Me, right? This isn't real. Right? This is these are hilarious, but they're not real. And and I guess what I what I'm trying to say is the the code that people are generating uh is creating a technical debt crisis, right? And that technical debt crisis is overwhelming GitHub. How many of

you how many of you noticed that GitHub's uh availability is down in the toilet recently, right? They've got like three times as many commits because of agents running a muck on the platform just this year, right? Compared to last year. It's an it's an incredible moment. I get it. We're producing more code, but that code has more debt and we're seeing people actually having to uh uh

uh there's more code churn and more roll backs and more refactorings going on and somebody has to do that. And the and the result of this is that we have more jobs, right? This is actually kind of interesting as well. Softer jobs are surging this year, right? People are realizing, oh, hey, maybe we did somebody to mine, we did need somebody to mine the shop, right? So,

this is, I think, an moment moment, an amazing moment. Softer job opening surging this year. There is an amazing moment. We have the best technology. We have the best ecosystem. We have the best runtime. We have an amazing amazing position in the enterprise as custodians of the business logic that runs the enterprise. And I mean, you know, they need us. It's an amazing time to be a

JVM and spring developer, my friends. Thank you so much for your patience. Have a wonderful spring IO. Appreciate it. All right, I want to get one more selfie. One more selfie this time. Here we go. Ready, steady, say. Open source. Uh, people always ask me what I'm going to do with those selfies. I'm going to take that and I'm going to show it to my daughter. I'm

going to say, "See, they listen to me.

From event

Spring I/O

13 Apr 2026 – 15 Apr 2026

All event videos
Back to Watch