Spring Boot 3 - Whatโ€™s new in Spring Framework 6 and Spring Boot 3.0

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments

Heated discussion in the comment section of this post. Well I for one liked the video summary on Spring Boot 3 and Spring 6 very much. I might suggest this new HttpService after we've moved over to Spring Boot 3 at work.

๐Ÿ‘๏ธŽ︎ 11 ๐Ÿ‘ค๏ธŽ︎ u/Hreinyday ๐Ÿ“…๏ธŽ︎ Jan 13 2023 ๐Ÿ—ซ︎ replies

Anybody actually managed to get the native image stuff to work? Even a pretty basic app chokes on ./gradlew bootBuildImage once I have logging stuff on the classpath, i.e. spring-boot-starter-logging

๐Ÿ‘๏ธŽ︎ 4 ๐Ÿ‘ค๏ธŽ︎ u/zman0900 ๐Ÿ“…๏ธŽ︎ Jan 14 2023 ๐Ÿ—ซ︎ replies
Captions
what's up Friends Dan Vega here and today we're talking about spring boot 3. unless you've been living underneath the Rock and oh my gosh if you are as for help please spring boot 3 and spring framework 6 have been released and wow they are packed full of really great features today is my what's new in Spring boot 3 video so what we're going to do is we're going to create a new project using start.spring.io we'll take a look at some of the major theme features such as moving to Java 17 Jakarta ee 9 and 10. we have a big theme around observability and of course one of the big headlines is being able to generate native images using coral VM there are also a bunch of other little features or maybe not headline features that I find fascinating and some of the supporting projects have some really great features in them as well so that's what we're going to do today this is not an in-depth tutorial into every single feature this video is long enough this is more of an overview of hey here are some of the things that are new in case you aren't aware so with that let's just get in write some code and start talking about spring boot 3 oh my gosh I'm so excited this is finally here if you want to read more about spring boot 3 there is a really good blog post here about spring boot 3.0 going GA I just kind of recap of what happened in this release that will also point you to the release notes the release notes are a great way to kind of get caught up on what's new in a release what's been deprecated what's been removed all the little features so go ahead and check out that blog post and the release notes but what we're going to do here is we are going to create a new project using springboot 3.0 and we'll go through and take a look at some of the new features some of my favorite new features by creating a project and going through and just kind of pointing them out as we go so we are going to use Java the start the spring initializer has changed a little if you haven't noticed the default is now Gradle and there's actually two versions of Gradle Gradle groovy and Gradle kotlin I'm going to choose Maven and we're going to use 3.0.0 I'm going to go ahead and fill this in we'll say dev.dan Vega and let's just call this a Blog we're going to work with the domain of a Blog so we're going to choose packaging of jar and Java 17 just a reminder that spring boot 3 spring framework 6 now require a baseline of java 17 so we need to be on at least that okay so we're going to do a bunch of things here but I want to just start out pretty simple we can go ahead and add some dependencies later I'm going to build a rest API I'm going to use spring data jpa and I'm also going to need a database I'm going to talk to an H2 database we are going to use a bunch of other things like Spring Security we'll talk about micrometer and some of the observability changes we'll bring in the actuator we'll talk about you know a whole bunch of other things that we need to but I don't want to kind of get worn down here by adding all these dependencies now this is all we need to get started so let's start with that and then what I'll do is go ahead and generate this project and I'm going to go ahead and open this up in my favorite ID IDE IntelliJ you can open up in whatever text editor our IDE you're most comfortable using all right so here we are in IntelliJ and before I get this question asked to me I know somebody's going to ask it because I've been getting a lot lately the theme for this is the new UI in IntelliJ 2022.3 and I believe this is the uh GitHub Dark theme off the check but that new UI is in the new version of IntelliJ that's what that's how I'm getting this look and feel so with that uh let's go ahead and talk about what we're going to do here today so again we're just going to kind of build an app we're going to there's not it's not a real app we're just kind of like taking a look at all these different features that I want to cover today so with that all the source code that we're going to go over today will be in the you know GitHub repository you can find the link for that in the description below the first thing I want to do is take a look at the palm.xml so we can see that we have declared version 3.0.0 and we are using Java 17 that is kind of again one of the big major headlines of springboot 3.0 if you go into the spring boot starter parent so on a Mac I'm command clicking and you go into spring boot dependencies you can get a list of all the dependencies that we've included in here that is why when you include something in your main Palm as a dependency you don't have to declare a version because we've kind of declared that for you we've said we've found this to be the version that works best so if you go into the readme for this repository you'll see I've listed a bunch of information in here around different versions of things now again one of the things here is Java 17 if you're coming from something like Java 8 not only are you getting huge performance improvements you're getting a lot of security features security updates as well as new features for developers right all the way dating back to like Java 9 if you're coming from that far back from 9 to 17 you're getting things like J shell local variable type inference using the VAR keyword and HTTP client switch Expressions text blocks records pattern matching sealed classes a whole bunch of really great developer productivity enhancements and features so I think that's the the big start for me is Java 17. now the next one is Jakarta ee9 slash 10. now why are you putting two versions in there Dan so let's talk about this let's go ahead and run this application and I want to take a look at the console here and if we look in here and we see that Tomcat was started we see that Tomcat is now on 10.1.1 so this is part of the reason that you'll see uh when we when we talk about spring boot 3 and the Jakarta ee version Jakarta is so we're using nine and ten in different places um it might be a little confusing but let's talk about why both of us did so spring boot 3 upgraded to Tomcat 10.1 as we see here since 10.0 was end of life already this has a dependency on servlet 6. the goal now is to provide a set of ee-10 providers in Spring boot 3 or as far as possible while retaining an ee9 Baseline for optional downgrades example Jetty 11 still uses servlet 5. so that's why we say if you see nine and ten that's a little bit of both what it boils down to is that we can support either 9 or 10 at runtime but only 10 in a test Suite that may use something like servlet this is because the the spring provided servlet mocks have a Servo 6.0 Baseline now um and again this this only this restriction really only applies to like mock-based servlets tests using something like test red rest template are not going to be affected so that's the move to Jakarta ee 9 or 10. what implications does that have well if you're in your own application and you're upgrading you'll have to change the namespace and what is the namespace let's take a look at that all right let's start creating our application by creating a new model so I'm going to create a new package in here we'll call this model and I'm going to create a new Java class called post inside of post this is we're using spring data jpa I'm going to mark this as an entity and right away you see we bring in jakarta.persistence.entity where this would have been Java x dot persistence in the past right so now if I want to I can say at ID private integer ID and again that ID is coming from jakarta.persistence so private let's just say user ID oops probably need an integer there Dan let's say we have a title man my typing is just all off this morning it's okay private string body so then what we'll need is we'll need a no ARG Constructor we need that for jpa sake and then we'll go ahead and get a Constructor where we take all arcs so there we go and then we'll just generate some Getters and setters and I know the question is why aren't you using lombok and yes I liked lombok for a while I just don't see the need for it now I don't mind generating this from the IDE I know you can't use records we are on 17 currently jpa doesn't support records again that's because it has this no Arc Constructor records are immutable so we have to like set everything and then we can't change them later right so that is the reason for that but again you could see using something like the IDE it doesn't take a long time to kind of generate uh that those that data all right so that's really what I wanted to show here that when we're pulling in uh the Jakarta stuff we are using the correct namespace again if you're upgrading you're gonna have to change Java x dot persistence to jakarta.persistence so with that we brought in a whole bunch of kind of updated libraries right um the list is in the readme below or in the release notes for the full list but we're getting updates to things like hibernate so we're on 6.1 of hibernate we're on hibernate valid editor 8.0 we're on Jackson 2.14 we're on r2dbc 1.0 which is great Tomcat 10.1 timeleaf 3.1.0 so check out the release notes for all the updates but that's um really great to see and I think I've said this on Twitter before I've said this in presentations before one of the things that I'm most excited about in this move to Jakarta is all of these apis that have been stagnant for years now we get to see them evolve these apis are going to evolve and and improve and get better and get things added to them so that for me is most exciting even though we need to put in a little work and change some namespaces it's going to be good for us moving forward so I'm excited about that the next big feature that I want to talk about is the headline of springboot 3.0 and spring framework six and that's grovium native image support this has been one of the biggest if not the biggest feat that the spring engineering team has taken on because again it's not just the framework itself it's not just spring boot it's the entire ecosystem of projects that need to be able to support this so Kudos hats off this ring team on on this amazing release and and this feature in particular so spring boot 3 applications can now be converted into a Graw VM native image which can provide significant memory and startup performance improvements this will require grovium 22.3 or later and the native image build tools plugin but you can read more about that in the documentation if you like so there's here just kind of an introduction to what grovium Native images are the differences with jvm deployments so the thing with this is it's not for every single workload if you have like this High throughput always up application then maybe that's not the case we've been asked this a lot on Spring Office hours lately when should I use a native image you know there are certain workloads that do work better things like serverless functions or Cloud native development depending on you know what the what the workload is so I would say you know figure out if if it's right for you if it is go ahead and test it out maybe maybe it is right the right situation maybe sticking with the gvm in your case in this particular applications case is the right move it's really about you kind of testing this out and figuring out which which workload is right the gvm is still great it does so many great optimizations at runtime but again in certain situations this is going to be a key difference going forward but what I want to get into is developing your first grawvium Native image application so that's what we're going to do we have an application and we want to generate a native image so we have the sample application which we do now and basically you can build a native image a couple of ways one using build packs so if you want to use build packs you can there's a note in here the builds are used for these images is paquetto build packs Builder tiny it has a small footprint and reduced surface attacks but you can also use paquetta build packs Builder base or Builder full um this also depends on what architecture you're using so I'm on a Mac OS I'm using arm if you're on Intel you know those two are different Builders build packs that it's using currently if you do it on Mac OS you'll have to check out my co-worker Deshawn's article on how to get this working if you're on Intel it should kind of work out of the box so there's some system requirements how to use Maven and then if you want to build that particular build pack one you can just say you're using this Dash p to switch to the profile native and then you're running the spring boot build image the same uh Maven goal that you would run before you're running now you're just using a different profile so that's cool so you can also do this in Gradle and then you can go ahead and run this example what I'm going to do is actually run this using the native image using the native build tools so let's take a look at what that looks like so if I go into my terminal here and I say Java Dash version you can see we are using guavi m22.3 so what I can do is I can say Maven Dash p again we're going to switch to the native profile but we're going to use the native tools now to compile this application so you're going to see it's going to bring a whole bunch of stuff down because I haven't done this yet here it's going to go through the native compilation now again there are trade-offs for this this is going to take a little bit of time but once it's done we'll have a native executable that'll run on this architecture this machine so we could push this somewhere else and it's going to be much smaller in memory which is really cool to see and a much faster startup time so I've done some videos on serverless spring so this would be a perfect scenario for that if you wanted to build a serverless function using spring Boot and spring Cloud function build a native image push this to a provider like AWS or Azure or Google Cloud now you have this smaller footprint and this image that can start up really really fast this native executable so again in certain workloads this is going to be really good I'm going to not let you watch this whole thing uh get bored watching this build so through the power of editing we will jump ahead to when it's finished all right so as you can see it took about two minutes this isn't something you'll do in your inner loop development all the time this is something that would happen say on a CI CD process to generate that native image but now let's look in our Target directory if we look in here we can see we have this blog this is the native image so if we wanted to run this we can just say Target blog and you'll see that it runs up whoop we got something in use already that's okay let's see what do we have running here we have oh this application is already running so that's why so let's clear this and just run this again and you see how fast that starts up that was instant 0.082 seconds now again this is a pretty trivial example so what did we gain here maybe a second or two but as your applications get a little bit bigger and a little bit heavier this matters uh the the footprint of the memory manners the startup time matters if you can cut a few seconds off and you have a thousand different instances starting up imagine the savings on your Cloud bills that you're going to be able to get so pretty cool to see there's a whole lot we can go into here but I just wanted to give a brief introduction into generating native images with graviam in Spring boot 3. all right so now I want to go ahead and continue to build out our application and that way I could show off a couple other little features that I'm really excited about so I'm going to create a new package here we're going to call it Repository and inside the repository I'm going to create a new Java class and we will call this the post repository now again this is an interface so one thing I want to point out here is that spring boot 3 uses spring data 2022 and there have been some really good additions there and act actually we'll jump over to the browser in a second and take a look at a bigger list but I just want to show off one thing here so in the past we might have done something like extends cred repository so credit repository and then what is the type it's a post and then it is the ID type is an integer so in credit repository we have all these methods that allow us to do things but one thing that's always been a little bit quirky is find all returns and iterable and we're used to working with things like lists so now you have to figure out how to iterate over this or turn that into a list and it's just one of those little things that uh you would like to change so what they did with the spring data team did was add a new list crud repository so again we can still use post as the type and then the integer is the ID type but if we look at list credit repository you see that it still extends credit repository but now it adds a few methods here and these all return a list so save all now returns a list find all now returns list and find all by ID now returns list so what does this really mean well this means that when I go to create a controller so let's create a new controller here we'll say controller and we'll say new Java class post controller and we're going to mark this as a rest controller we're going to have a request mapping of Slash API slash posts and in here we're going to get an instance of that post repository so we'll say private final post repository post repository we'll get an instance of this through Constructor injection now what we can do is we can have a git mapping for um public list of posts find all and now we can say hey give let me use that post Repository and I want you to go ahead and find all now if you did this before we yell at you and say hey uh credit repositories returning an iterable and you're trying to return a list again just one of those little nice things that makes everything line up a little bit easier now what this does mean is you can see that in the list cred repository we're basically extending credit Repository so there's two of these different types of crud repositories right there's list and there's regular crud so what this means is if you were going to use something like paging and sorting Repository this takes a post and an integer just like the other two you could see that this extends repository now this well this used to extend crud repository now we don't want to do that now because we want to give you the choice to extend either crud or list so if you want to extend you can go ahead and extend the other one as well list cred repository and that would go ahead and take a post and an integer as well so that is just a small change but uh something that you know it's just those little things that I always love and the spring data team is really helping us out there and uh given us these little nice little features here so if you look at the spring data 2022 release notes you'll see kind of the general themes again they've upgraded to Java 17 Baseline spring framework six Jakarta 10 and you'll have all of the head of ahead of time uh processing and all of the hints to create your grovium native images there's a bunch of observability integration with micrometer and my micro micrometer tracing so we'll look at observability in a little bit but all of that's been baked into the spring data project and then a couple things right here that we just talked about so there's Now new variants of the credit repositories we saw the list credit repository there's also the list query DSL predicate executor and the list query by example executor these return list methods that return multiple entities so because of that sorting repositories no longer extend that credit repository so we saw that with this you know the other ones are kind of following suit so that just means that you must extend that explicitly um and then there's just some changes to behavior about the delete methods and revised Constructor Discovery for Java records so a whole bunch of really great stuff I'll leave a link to the spring data release notes I just thought I wanted to point out those us again kudos to the spring data team for those changes here in Spring boot 3. next new feature in Spring framework six that I want to talk about is HTTP interfaces before we can do so though I want to step back and talk about our application we'll go through a normal progression of how we might build this out in previous applications and then we'll see where HTTP interfaces really come in and save the date I want to load a bunch of blog posts but I'm going to get this from another service this is not coming from this particular database I want to load some initial blog posts from another service so let's take a look at that service the service is a public API called Json placeholder and if we come down here we can see that we have Json placeholder comes with common resources like posts and you could see this is the post that I want to go ahead and load and this is why I modeled my post entity to look like that so I had an ID a user ID a title and a body so what I want to do is I want to take this and I want to go ahead and import those into our application so what I'm going to do is I'm going to create a new service we'll call this post service oops I'm sorry I meant to call this service and inside of service I'll create a new Java class we'll call this post service and I'll mark this with the ad service annotation so this gets picked up so what I want to do is I want to create a method that returns a list of posts we'll call this load posts and so somehow I gotta reach out let's say call the Json placeholder service and return the list of posts so how would I do this so in a normal application before spring boot 3 I basically had two options well you you can go low level and use some other options but in the spring world we have two options one we could use a rest template because we're in the spring NBC world and we don't care about not non-blocking IO you know we are in a blocking servlet world right now so rest template works fine if you were in a reactive application you could use something like the web client but uh rest template works fine for what I want to do here so I'm going to go ahead and say uh private final actually let's say rest template rest template and actually I do want to mark this as final so what I'm going to get is this through Constructor injection I don't have actually have a bean of type refs template so I'm going to create one here in my main application class because this is a configuration class and I'm just going to say rest template press template return new rest template so that works that should satisfy that and now I have a rest template that I can use so I want to say rest template dot exchange so when you're returning like a list of things back uh it gets a little quirky you need to return something called a parametized parameter parameterized type reference say that a couple times fast so we're going to pass in the URL that we need to so that is that Json placeholder this is going to be a get so we're just getting that and can we get these on separate lines yeah and then the request entity is going to be no we don't care about that and then the you can see the return the response type we're going to use that new parameterize type reference which is going to be a list of posts and that looks good does that look good yes it does so now what I can do is just return the uh we need to set a local variable here sure we'll call it exchange return exchange dot get body so that should give us our list of posts okay now that we have this load posts method we can go ahead and use this somewhere to load all these posts into our database uh to do that we're gonna have to do a couple things I think the first I think the first here is I'm gonna come in here and um I'm just going to rename this to application.yaml I'm going to use the yaml file in this particular demo because we're going to be doing a bunch of properties later when it comes to observability but the first thing that I want to set is the data source name so we're going to set this to blog so we also want so we have a spring.datasource.name we also want to generate a unique name false so we're going to set that so now we have a database connection because we're using that H2 in-memory database but now I need a way to go ahead and call that post service when the application loads and feed all of those posts that I just grabbed into the database so for that I'm going to create another Bean here we're going to call this uh this is of type command line Runner so again if you're new a command line Runner is a functional interface this means that there's only a single method in here a single abstract method and that it is a great Target for a Lambda expression so we can just go ahead and use any use a Lambda here instead of implementing this interface and overriding this run method so we're going to call this command line Runner we're going to get an instance of our post service here uh because we're going to need that to go ahead and insert or call our load posts and then we can go ahead and use our post repository to save that so let's also get our post repository instance in here as well so this is going to return this and here we go so now the first thing I want to do is load all of those 100 posts from the Json placeholder service so to do so I'm going to say post service and then we're going to call the load oops wrong one Post Service dot load posts and I'm going to create a VAR from that and that will create a list of posts called posts once I have those posts back I can use the post repository to save all of those posts so I'm going to pass in post and now I can go ahead and introduce a local variable if I want to there so sorry I didn't want to do that I wanted to use post repository.save all posts and I don't need a local variable because we're not going to do anything with it so now at this point when the application loads we're going to call Post Service load post we should get back those 100 posts from the um Json placeholder service and then when we return that we'll just go ahead and call our repository.c ball and persist those posts to the database so let's run our application we didn't get any errors so that's a good thing so again one thing I want to point out here is we talked about this earlier but we are on the latest and greatest version of hibernate so we're using 6.1.5 so we are up onto six there's a whole bunch of good features on six going forward so if you want to check out the hibernate documentation on that we have our connection to our jdbc H2 and memory database called blog with the default user of sa so what I want to do is oh we actually didn't enable the um we want to enable the H2 Council so let's re-run this application and then we could go ahead and jump in there and take a look at the database all right so I'm gonna go ahead and check use the blog database the username is SC we can test that it looks good if we jump into the post table we can see that there are now a hundred rows in there so great so that tells me we were able to call out to the Json placeholder service we were able to then use that server use those posts and load those into our database all right so that worked there's actually nothing wrong with that code if you want to continue to write that code go ahead but what's Happening Here is we basically are telling spring hey I want to list the posts here's the service that I'm going to call but now you need to do this dance with the underlying HTTP client by using this rest template and calling this exchange method and then figuring out which method to use which parameters to call if you look at the API there's just a ton of methods in there a whole bunch of overload methods ah what do I use I just want to list the posts and that's really where HTTP interfaces come in the spring framework lets you define an HTTP Service as a Java interface so the same way that we do with our repositories with some annotated methods for things like HTTP exchanges you can then generate a proxy at runtime that implements this interface to perform those exchanges this really helps simplify any HTTP remote access which often involves this facade that's wrapping the details of using that underlying HTTP client so what I want to do is move away from the post service we're going to keep this class in place so you can see it in the repository but what I want to do is move away from this all right we're going to say we're not going to do that here we'll come back to this in a second but what I want to do is just declare an interface that has the methods that I'm interested in about with the service that I'm interested in talking to so what I'm going to do is create a new Java class here we're going to call this Json place I'm going to actually Place holder service and again this is an interface and what we're going to do here is we're just going to define the methods that we're interested in so we know that we want a list of posts we're going to call this load posts and how are we going to retrieve this information well this in this particular one this is a get so this is going to be a git exchange so there are also things like Post Exchange delete exchange Etc so we're using the git exchange to um slash posts so there'll be a kind of a baseline URL for this service somewhere so if we look back in our post service this can be the Baseline URL and then in this particular case all we want to do is call slash posts off the base and that that is what we're going to call to get this list of posts then what happens is we're going to write a little bit of code and this at runtime will get turned into an implementation that we can now use so this is a lot easier right all we're doing is defining one single method here with uh again this is a this is an interface we're defining an abstract method here instead of what we did before which was try to figure out that song and dance of like what method do I call what parameters do I get a path this weird thing with the parameter type reference you know we don't have to do any of that anymore we get this simplified method here so how does that turn into what we needed to turn into so we do need to bring in the web client because the web client is what's going to kind of drive this so what I'm going to do is go into my palm.xml and I'm going to have a dependency on Spring boot starter web flux and that's it I'm going to go ahead and click save or reload uh make sure that's okay and it seems like it is all right so what I want to do here is use the web client dot Builder do I not load yet um web oh that's why let's bring that in all right so we're gonna use the Builder we're gonna set a base URL again we're going to go back to that post service I'm going to set this as the base URL not d slash posts right and actually I don't want that I just want that so we're going to set our base URL to that and we're going to say build and we can introduce a local variable here let's go ahead and call this client and then what we'll need is we'll need something called an HTTP service proxy Factory we're going to go ahead and call Builder on net we're going to say web client whoops web clients adapter why that's not coming in there we go so for client we're going to use client and build and finally now that we have that HTTP service proxy Factory in place what I can do is I can create an instance of that Json placeholder service so I can say Json placeholder service is equal to factory dot create client now all we're doing is creating that client and we're going to pass in that type so Json placeholder service dot class so now I know you're probably saying that this seems like a little bit of overhead and it might be but this is going to be consistent for each one so what you could do is just come in here and create a like for me I create like a live template in IntelliJ to Output this every single time so that I don't need to go in and type this so once you have that boilerplate down you get this Json placeholder service you now have an implementation of that interface so what does that mean so that means now we can just say hey Json placeholder service go ahead and load posts and that is going to give me back a list of posts now I can come back to my post repository.save all if we go ahead and run our application everything looks okay um actually yeah that's a different error so don't worry about that let's go back to the browser check out the H2 console connect to that look at post and we still have our 100 records so cool so that is HTTP interfaces allowing us to just declare this interface and the methods that we care about so again this is working with a public API like I have in this instance maybe you're calling another service within your application or your microservice so you can just declare a a service that is going to call that service and then you list out the methods and the exchanges that are going to happen there and then we will turn this into an actual implementation and you don't have to worry about all the like nitty-gritty which method am I calling which parameters am I passing this just is going to work for you the next really big theme in Spring mood 3 and spring framework six that I want to talk about is observability so observability is the ability to observe the internal state of a running system from the outside this really consists of three pillars which are logging metrics and traces for metrics and traces spring boot uses my micrometer observation and more importantly distributed chases are now wrapped up into micrometer whereas in the past we might have reached for a third-party Library like spring Cloud sleuth so this is all rolled up into micrometer which is really good gives us one place the other big thing is this is a consistent API that the framework is now using to gather metrics and traces about what's happening in your application as well as this API that you can now use in your application so there is a lot to cover here I cannot cover all this in this short video we're going to just take a look at a couple things I'm going to leave this a link to the reference documentation this is a really good place to start I would read through here understand about these kind of low cardinality key values High cardinality key values there's a tip here for the jdbc observability which we are going to do um go ahead and take a look at that and then the micrometer observation documentation is really the next place to start to understand how all of this works so for me I'm going to come into the Palm here I'm going to add some dependencies again if you go ahead and add these from like the spring boot starter or from start.spring.io you can kind of pull these in uh with as you're building out your application but we're doing this as we go so I'm pulling in a couple things again this is what I got from the documentation the other thing I need to do is I need uh the actuator so actually let me go back to here we didn't pull in the actuator yet did we nope so let's say dependency actuary spring boot starter actuator and let's pull that in so now that we're using actuator we're starting to collect all of these metrics what happens is when these things are being instrumented behind the scenes for us we now need a place to kind of view some of these things like these traces and so what I'm going to do is use a tool called Zipkin so we've pulled in the dependencies that we need to kind of connect to Zipkin I need to run a local instance of Zipkin to get this up and running so to do so I'm going to run a Docker compose file so dockercompose.yaml I'm going to go ahead and copy and paste this in but what this will do is allow us to start up an instance of Zipkin so let's just go into our services I want to see if this is already running because I've done uh oh yep so this is already running uh let me make sure this is stopped all right now that we have Zipkin running let's head over to our pose controller I just want to take a look at this so what we're going to do is we're going to make a few changes to our configuration and then we're going to launch our application and we're going to go hit the slash API slash post endpoint and we're going to see that some metrics and traces are being gathered for us underneath the hood thanks to the framework right um so this is one place that we're going to kind of get all this out of the box for us just by including the actuator and the right dependencies and then what we'll do is things like this that we are going to another service for that we are calling here in our command line Runner this is not being estimated this is our own code so we'll have to find a way to do that and lucky for us as I said at the beginning this is all that single consistent API that the framework uses and that we can use as well so let's take a look at this I think the first thing we need to do is go into our application.yaml and I've added a few things here for configuration just making sure that the health endpoint is on that we're including all the endpoints this tracing sample Pro sampling probability is a value of 0.1 to 1.0 and it's how much sampling do we want to take here I'm in a Dev environment I'm just saying always always sample always collect this data for me because I want to see it so with that in place I'm going to go ahead oh I don't want to run Docker compose Dan that's already done what I want to do is I want to run this so go ahead and run that for me and if this starts up okay and it does let's head over to the browser and I'm going to go to localhost 94111 that's where we set Zipkin to run on so Zipkin is this tool we can look for traces if I go ahead and run a query I'm going to see a whole bunch of traces in here these are just connection traces that are being done these are instrumented thanks to the jdbc called one of the dependencies that we included on there so if we go in there we can see that we have a connection to an H2 database we can see we kind of Select to see some things going on and then down here we're inserting into the body title user ID this is because the repository itself is instrumented so when we say post repository.save all that's instrumented this is not so we don't see anything for this call so what I want to do now is just go to localhost 8080 slash API slash posts and now I see all of the 100 posts that were loaded in so now if I go back to Zipkin and run this query now we're going to see that call being made so if I jump in here I can see some information about this I can see no tags here's the URL it was a get method it was successful the status code is 200 here's the URI we can see that the this was the call this was the total duration of that call if you start to drill into it and it does a whole bunch of different things we get instrumentation on those things this just happened to color repository and return all the records from the database so we can see our connection again we can see that we are selecting from post and hey here's the row count we get a hundred rows back so again that was just that find all method so cool so far so good we're getting a whole bunch out of the box but now we want to go ahead and do some things ourself so how can we do that again back in the documentation um you can take a look at this I'm going to go ahead and delete that particular call and what we're going to do here is we are going to say observation and now from the observation we can do something called create not started this is going to take a string name and then an observation registry so the name is anything that we want to add here so I'm going to just say this is Json placeholder load actually let's say load posts so now I need an observation registry luckily um it is one has already been created for us and it is in the spring context so I can just add a argument here to my command line Runner and because it's there now I can just say observation registry and now we need to do a couple things one we could set a low cardinality key value so if we set a low one we could say just some value and we could set a value for this and I'm just going to say 88 again this is these are kind of like tags that you would want to track right what do we want to track here so I'm saying that and then I'm going to go ahead and observe something so what are we observing and why am I getting this funky oops oops let's close this why am I not getting anyways okay so now we want to observe something what do we want to observe so this if you look at this takes a supplier so we could come in here and we could say use a Lambda here and then say JPS GPS dot load posts but because we are not passing an argument here we can also just go and ahead and use a method reference so I'm going to do that so JPS load posts and now that works so what we're doing is we're using the micrometer observation API that the framework and all the projects across spring are using we get to use that same observation API we are creating something not started um we are because we're not starting this yet this is actually what kicks it off right The observed is what is the code that we're actually observing that we're trying to take a look at and that is the call to another service that is going to load posts so finally we need to introduce a local variable here and call this posts because we're going to get that back and now we can go ahead and save all using the post Repository so with this in place I think I'm going to go ahead and restart the application let's make sure that runs okay and it does I'm going to head back over to Zipkin here I'm going to run this query and now you see we have this Json placeholder load posts so if we go into there we can see that the execution of this took 470 milliseconds here's that sum value that low cardinality key value that we set so we could start to dig into that as well we don't see the repository happening so let's go ahead and do that as well so let's get rid of this and say observation dot create not started again we're going to say post Repository dot save all we're going to pass in the observation registry and here we're just going to observe we don't need to set any but key values this is again takes the supplier so I'm going to say post repository dot save all and we're going to pass in posts we don't need to return anything here so that should be good let's go ahead and run this again and we'll run back over to the browser take a look at Zipkin and now we see this post repository.save all so if we dive into this we can see what happened there's a connection here's everything that happened in our application so cool so again I think one more thing I just want to point out is in application.yaml in the final version that you will see over on the repository I'm going to include a little bit more configuration so let's just go ahead and paste that in you can find out more about this in the documentation that I linked you to as far as setting up the jdbc logging or jdbc instrumentation so a whole bunch of properties here that can kind of fine tune that I set up a separate logger called data source query logger it's using sl4j do you want to include the bind bind the parameters values in those spans you could set a Json format on not you may not want to include everything in that logging so I may do I want to collect data on all the connections fetches and queries this is what it's going to include by default but you could just say hey I just want queries and then now that I have that login that logger I can go ahead and set that log level for data source query logo so just some additional configuration you can have which again is nice because now you can have separate configuration for development testing and production so cool so I again I included some links in the GitHub repository this is really just the tip of the iceberg observability between logging metrics tracing more importantly distributed tracing is a huge theme in Spring framework six spring boot 3 and all of the portfolio projects across the ecosystem the next feature we're going to look at is problem details for HTTP apis and a common requirement for rest Services is to include details in the body of an error response the Supreme framework suggests and supports the problem details for HTTP API specification which we're looking at here now I'm not going to go through this whole thing but this is a really nice spec that talks about what the problem details specification is it goes into kind of the introduction what you might want to use it for and hey a lot of the times we get this um response that has a 403 and it doesn't have a lot of information in it and we want some more information in it so how can we do that so read through the spec if you want you do not have to read through the entire thing I've read through like the first three sections and that's really all you need and to understand what you can put into a problem detail so we're going to look at kind of a trivial example here but it will make sense and give you a little bit more insight into what this problem details can do so here in my post controller I'm going to create a new method here and this is going to have a get mapping of uh Slash ID and this is for when I want to find a particular post I may say public post find by ID from the path variable I am going to get an integer called ID and what I want to do is return from the post Repository I'm going to call find by ID I'm going to pass in the ID this actually returns an optional so optional of type so what I want to do is say or else go ahead and throw an error and what is that error going to be so again else or else the row takes a um well that one doesn't this one takes a supplier so we can go ahead and say I want to throw a new so I could throw a runtime exception here but I'm actually going to throw a new post not found exception and we'll pass the ID so I'm going to go ahead and create this so I want to create this let's go ahead and create a new package we'll call this exception and we'll say new Java class post not found exception so this is going to extend the runtime exception and in here we're going to take in the integer ID we're going to have a Constructor that takes that in cool so post not found exception takes the ID and then we need a way to get and set that ID and there we go so this is saying um Constructor post oh is never used so um there we go cool so now let's go ahead and try to restart our application and then if you don't know we do some content negotiation right so if we go to all posts we get those if we go to posts 99 that is actually a valid one if we go to 999 we're going to get an error so we get in we just get this generic error page with a status of 500. if we do this if you look in the council you'll see that we've hit that post not found exception if we run to the terminal we can do this we could say so I'm using HTTP just an easier way to use Curl underneath the in in terminal curls kind of verbose HTTP is pretty simple so I can just say I want to call 8080 slash API slash post slash 999 and you can see that we're getting a 500 here so the type is application slash Json I'm just getting an internal server error here's the path here's the status not a whole lot of information right so one way we could fix this is we could actually come in here and set the response status to http status not found and if we refresh or restart this application and then go back to the terminal so a little bit better I have a 404 it just says not found 999 not found so this again is kind of an arbitrary example because I don't have a real example here in the post but in in the spec there was like a really good example of hey you're hitting off forbidden but why is it forbidden you don't tell me why I'm getting I'm not allowed access to this and in in the scenario I think it was like oh you don't have enough money to be able to access this or something like that so a lot of times like a 401 or a 403 may not be sufficient I need more details about why this is failing and so this is where the problem details comes in so what I'm going to do is expand upon this I'm going to create a new Java class in here called exception Handler advice so what I'm doing here is saying that this is a rest controller advice so this annotation if we go ahead and look at it says this is a convenient annotation that is itself annotated with controller advice and response body types that carry the sanitation are treated as controller advices where exception Handler methods assume response baddies semantics by default so at the end of the day we're just allowing a way for us to catch these errors and provide a little bit more detail in this case so what I want to do is I'm in this class I'm looking for an exception Handler of type post not found exception so anytime a post not found exception is drawn this is going to get called so what I'm going to return from this is a problem detail so this is the new part this problem detail class if we jump in there um represents a representation for an RFC 7807 problem detail that's the spec that we looked at in a properties map for additional non-standard properties so um yeah just uh to be able to include those standard properties are things like title status detail instance and then if you want to attach non-standard properties you can use this properties map so let's go ahead and say this is let's call this handle post not found exception this is going to take a post not found exception e and that's good so what we'd want to do now is create a problem details so we can say problem detail dot for status and details so again there are some helper methods in here this one is going to take in a status code and the detail so in this code in this case the status code is going to be not found HTTP status code oh why am I status not found and then e dot get message will just get the message from our post not found exception class okay so there's our problem detail Let's uh create that problem detail at the end of the day we're going to return that that is the requirement here we are returning to problem detail so I can also add information to this if I wanted to so I could say problem detail dot set property so I want to set this property I want to go ahead and say the post ID is equal to get ID and then there are types so the type is again backed from the spec if you wanted to point someone to some documentation that clearly and explicitly defined what was happening here you could do that so I could come in here and say uh set the type and this would be a URI so I can say a new URI and this would be to something like localhost 8080 slash problems slash post not found I'm not going to include this but if you are going to include the type then you should include that in this case we also have to go ahead and add that exception and cool so I think that's all we need to do there um yeah so that looks good so now because this rest controller advice and this exception Handler annotation when this gets caught we should see that so let's go ahead and restart this and go back to the terminal I'm going to clear this out and run that again now you can see the content type is application slash problem Json so this is the content type and we get some more info here so here's the instance post ideas that thing that we added to it here's the status title so we can change that if we want type here is some more documentation on why this error is being thrown so again when it comes to http apis just being able to supply more information of why this result is happening is a good thing so this allows us to do that I also mentioned that you'll want to go into I think let's say by default so problem details is looks like it's off by default but I do want to enable that so that's a spring NBC problem details enabled equals true so you want to make sure that is set so cool again I've included some links in the readme to the documentation on the spring framework side as well as that RFC don't don't read the whole RFC unless you're an RFC nerd then go ahead but just the first couple of sections that really kind of talk through the problem and what problem details solves is good enough so cool so that's problem details let's go ahead and move on the last thing I want to mention are some changes in Spring Security now I've done a full video on this so if you want to check that out I'll leave a link to that in the description below but I'm going to quickly cover that here just because you are here why not let's take advantage of it our time together is limited let's go ahead and talk about it while we're here so I'm going to go ahead and include a spring boot starters starter security um there we go security um no that's not what I wanted security that's what I wanted now let's refresh this everything looks good and if we go ahead and start this application we know that by using Spring Security in the past we have some things secure for us so we're secure by default we get this default secure user or default user with the username of user and a password that is generated for us each time now what is going to change is at some point we're going to have to provide our own configuration right so we're going to come in here and we're going to create a new Java class we're going to call this security config and in the security config we used to extend the web security configure adapter you can see that's no longer a choice this use this was deprecated at some point and we were still able to use it in Prior inversions prior to springboot 3.0 but spring boot uh Spring Security Six has removed this so this is no longer something you can use you need to move to a new uh Model A more component based model of declaring beans in your configuration so to make this happen we are going to enable web security this is going to be a configuration class because we are going to create some beans and then to do so we'll create a bean of type security filter chain we'll call this security filter chain which takes in HTTP security and at the end of the day we are going to return http.build this is going to throw an exception and then when we come in here this is where we start to configure Spring Security so that is the first change that web security configure adapter not only deprecated but removed all right and so the next thing is uh we used to come in here and say authorize requests you can see there's a strike through that it says that has been deprecated we want to move to authorize HTTP requests so now we can come in here and we can say auth dot any request go ahead and make sure we're authenticated um so that's number two and finally in number three when we wanted to use some type of matcher so we had um say uh we wanted to take a look at uh okay for home I want you to go ahead and permit all we used to use maybe an ant matcher an NBC matcher a regex matcher those have all been deprecated uh and removed in favor of request matches we want to use a request matcher now and if we wanted to say hey the route for this project I want you to go ahead and permit all to that anything else is authenticated so number one web security configure adapter has been deprecated and removed instead of authorized requests you want to move to authorize HTTP requests and instead of using ant matches MVC matches or regex matchers we want to use request matchers so that's it just wanted to kind of quickly walk through some of the changes in Spring securities six again if you go check out that video we talk a little bit more in depth about that and link to the release notes for Spring Security Six where you can find out all of the changes that have happened in it wow that was a lot and congratulations to you if you're still watching this video you are a true spring boot fan I I'm a big fan of yours now um so as I said at the beginning this wasn't an in-depth dive into every single feature we didn't even cover everything that's in Spring boot 3 and spring framework six this is more of a hey here here's what's new in case you weren't aware of some of these features some of these we could spend long deep dives into like observability and generating native images with groovyum but we can so what I want to hear from you in the comments below or on Twitter reach out to me what are you excited about when it comes to Spring boot 3 what features are you really excited about are you going to make the upgrade if so what features are kind of driving that for you so that's one two is anything that we covered today was there anything you didn't quite understand if there was and we need to do a little bit more of a deep dive that's fine as well again let me know in the comments below but friends as always if you found value in this video do me a big favor please go ahead and give me that thumbs up on this video subscribe to the channel so you don't miss my next video and as always happy coding [Music]
Info
Channel: Dan Vega
Views: 27,057
Rating: undefined out of 5
Keywords: dan vega, spring boot 3, spring boot 3.0, spring boot, spring boot 3 graalvm, spring boot 3 new features, how to migrate to spring boot 3, what's new in spring 6 and spring boot 3, spring, spring boot tutorial, java, spring for beginners, spring framework, spring boot rest api, spring boot tutorial for beginners
Id: TR254zh-f3c
Channel Id: undefined
Length: 70min 47sec (4247 seconds)
Published: Fri Dec 09 2022
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.