跳到主要内容

How to create your own custom Spring Boot Starter(原声文稿)

· 阅读需 16 分钟
Dan Vega

Today, we're going to build our very own custom Spring Boot starter.

undoubtedly come across Spring Boot starters.

the web starter, you'll get this nice dependency, the Spring Boot starter web in your build file.

auto configuration to get you up and running.

configuration really help us bootstrap our applications quickly.

how to create our own starter from scratch.

information that you can come back to later and read if you want to.

There is a section on starters.

What are starters? I want to look at this section here that says what is in a name.

It says all official starters follow a similar naming pattern.

name is, where star is the type of application.

should not name your starter spring boot starter Dan, for instance.

starter, for example, a third party starter project typically be named third party project dash spring boot starter.

something from the official spring boot team Or is this something that someone has created their own third-party starter?

there and if you really just get in starting includes the auto-configuration support, logging, and YAML.

documentation for creating your own starter.

today, but this has a little bit more information.

through some configuration keys, what the auto-configuration module does, where you have to kind of put a file to read from this, and more.

structure application We'll see we're just gonna create a single project today two projects one for the auto configuration through it all. So to get started.

We're gonna be creating a spring boot starter after the JSON placeholder service.

this would be a pretty decent example of creating our own starter.

to go get 200 to-dos, I just include this client and boom, we're off and running.

We have some to-dos to work with.

So that's what we're gonna create now to create that. I'm gonna head over to start.spring.io. We're gonna create a new Java project.

version of Spring Boot at this time, which is 3.2.2.

dev.danvega.jps for JSON placeholder service.

service Spring Boot Starter.

That seems like a really you need to make this work.

As I said, we're going to kind And so all I need is the web package because client and then I can call it to another service deserialize, uh, whatever these types we're working with.

I will download this and I will open this you can open it up in whatever text editor or IDE Now, our Spring Boot starter is not going to be an application.

So application class. I'm going to go ahead and delete that now.

We're not going to read in from properties, but those will be filled in by whatever application defaults. We'll talk about that.

Those are the two things palm, all I have right now is the Spring Boot starter web.

going to do is I'm going to get rid of this build plugin.

We don't need the Spring Boot Maven plugin.

Again, we're not, we're just not going to use it here in this starter.

So that's some kind of infrastructure plumbing. Let's go ahead and start building our application.

is some properties to configure the JSON placeholder service.

So I'm going to start with, and actually I thought this was going to be JPS.

Yes, all directories, I don't need that.

So let's get rid of that.

Refactor, Awawa here. I think I will go ahead and get rid of this test as well.

That's not gonna work. So in here, I'm gonna create a new Java class.

We're gonna call this the JSON placeholder service properties.

properties, it's a good idea to have some convention around it.

can name it whatever you want.

So we are going properties.

And we are going to call it the prefix is And I actually don't want this to be a class.

I want this to be a record.

And in this record, we're going to have a single property, which is to use this base, we're going to use this base URL service, I want to set a default here.

The reason I'm property is you can actually download the JSON placeholder own local machine, and then it would be running at have that service that I was going to use in my demo.

I could URL in whatever application I'm the demo app that So I can use the at default value annotation we're using in the public URL if somebody wants to override that in their own application they can.

So we're getting some red squigglies here.

application class at enable configuration properties. There is no main app class here.

create a configuration, an auto configuration class.

So I'm gonna go ahead and say new Java class.

holder, service, configuration, yeah, that looks good.

documentation that we were looking at earlier.

This is something you want to go through to learn what we're going to do there.

placeholder service properties that we just created.

instance of a logger in here. I'm also going to get those properties.

I need those properties, and we'll get that through constructor injection.

configure all of the beans that I might need in my application.

the different endpoints on JSON placeholder service.

There are things like to do's and users and comments and photos and albums.

and we can always come back and do more later.

But I'm going to do the to do so I'm going to come in here in the to do package.

And we're going to quickly create a record to represent a to-do.

So let's go ahead and say to-do.

And this is a record. And what is it? User ID ID string. Yeah, that looks pretty good.

Yeah, that'll work for me. So now we have a to-do. So now what I need is a to-do client.

I'm not going to call it to-do client though, because that seems pretty generic.

You might have something like that in your own application.

do client, and this is going to be a class.

And in here, we are going to do a couple of things.

One, I'm going to get a logger.

And then two, I need a rest client.

So I'm going to say private final rest clients, rest clients.

And then in the constructor, we're not going to get an instance of this just yet.

basically got an instance of the default REST client by using RESTClient.builder.

Here what I want to say is RESTClient, RESTClient.

And I want to get an instance of the rest client and then set this.

So I would say this.restClient is equal to restClient.

But right now we don't have an instance of this bean.

have a restClient in the application context yet.

configuration class and create a bean of type restClient.

Client, and then what I'll do is get the RESTClient.Builder here, builder, set the base URL to whatever we get from the properties file, what's getting set there, and then build a REST Client.

And so now with that REST client, we can go ahead and create a bean of type JPS to do client.

So now I can say at bean, oh and loops, I forgot the bean here, bean, what is this not like?

Okay, we will fix that in just a second.

And then the other thing I want to do is go ahead and create the JPS2DoClient, REST client and then return the new JPS2DoClient.

so we're not, this kind of tripped me up the first time I did this.

We're in an application, but we are not in an application, right? There's no main application class. All right, so we'll come back to this in a second.

class, then how does this auto configuration run?

Well, there's actually a convention for making this work.

This was different in previous versions of Spring Boot.

You had a spring dot factories file.

little bit, So we need to go into resources.

We're going to create a new directory.

We're going to create one called meta inf and then one called spring.

And then in the spring directory, I'm going to copy this. This is in the documentation. We are going to create a new file. So new, oops. So new file.

And it's going to be that name, which is org.springframework.boot.autoconfiguration.inports.

anything that we want to go ahead and import for auto-configuration.

I'm going to give that fully qualified class name.

So I'm going to say dev.danvega.gps.jsonPlaceholderServiceConfiguration.

And now that we'll go ahead and get picked up.

So let's go ahead and let's just make sure Maven's reloaded.

And we have all of our errors gone.

Everything seems to look pretty good. I'm going to go ahead and just do a quick build.

Make sure we have no build errors. I think we're good.

So now the question becomes, how do I test this, right?

Because I don't have a main application class.

me kick the tires a little and see if everything's working.

And if I don't have a main application class, like how can I write some tests?

This is the one thing that kind of confused me as well.

my GPS to do client and I want to create a test for this.

Let's create a test. We'll create this in here.

And what we can do is we can get access to an application context runner.

And this runner is going to say new application context runner.

and then we can use the dot with configuration, right?

Because we need some configuration.

All right, let's actually give this a name, Dan.

And then we need to pass in some configuration.

So you can pass in a configuration, configurations.

But in this case, I want to say that I can't I have to actually pass to be this JSON placeholder service configuration.

That's the wrong one, I think auto configurations that we want the JSON placeholder configuration service that class.

client auto configuration because remember we have a being of rest client that is basically the rest client builder which is an interface.

when Spring's auto configuration kicks in but it doesn't in this case yet.

So if we were to try to run this now we'd have all kinds of issues there.

So I'm going to say the rest clients auto configuration class.

So now with this instance, we could do a couple of things. I'm going to go ahead and copy and paste here.

But now we can do something like this.

We can say, hey, take the context runner, run it. And from there, I want to assert a couple of things.

One, that we have a bean called JSON placeholder rest client.

actually let's stick to what I have in the repo.

So the way that I would have done that in the repo is I would have said, uh, bean.

And the name is Jason placeholder rest client.

name of rest client because I use that in a lot of places.

make sure those two beans are in the application context.

means we've done our job, and those beans, that auto configuration file is getting picked up because of this file, this import file and those beans are getting placed into the application context.

So from there you can just do there's a there's some a couple tests that you can do I'm gonna go ahead and paste these in here but they will do a couple things right I want to make sure that there's a default base URL right I also want to check to see hey if I override that service that base URL I want to make sure that that is sticky and then there's hey let's go ahead and make implementation in the client yet, which is fine.

But I just working. So let's go ahead and run that. Cool.

So to our to do client, we're actually not doing anything yet. So let's just run copy some code in again, copy pasta.

This is not placeholder service with the REST client a couple times.

call it to the service and find all or find one or we might do.

So back in my test, let's go ahead and pull those other files back up.

and test that the JSON Playsolder service is working.

What are we complaining about here?

find all the JSON Playsolder service has 200 to do's.

So we are actually reaching out to it in this instance.

And then we're double checking that the one well. So cool. So not a lot to it.

That's kind of our of things.

We removed some of the boilerplate code application. We created some properties, a configuration class.

convention. And and then everything gets picked up from there. And we also saw how we can test some of this.

So with this in mind, I think we're ready to use this in an application. So let's figure out how we can do that. All right, so I am here in my M2 directory. The project that we built is using Maven. So I'm looking in my local M2 repository here.

I'm going to CD into repository.

repositories, again, mine is under dev.danvega.

So I'm gonna cd into dev danvega.

anything about that GPS custom Spring Boot starter. So I'm gonna go in here into my terminal.

I'm gonna say maven clean install. And I'm just gonna kind of force that.

If everything goes okay and it did, see a JPS.

So if we go CD JPS in here, we have a JPS boot starter that we're going to have is based on spring boot starter.

And then the version is 0.0.1 snapshot, so if we go in here, we'll see there's a 0.0.1 snapshot.

this again, there'll be a second version in there.

repository, in my Maven repository there, when I go ahead include it as a starter in my dependencies block in another application.

Central and so that everybody else can use it.

We'll do that in a separate tutorial.

create a new Spring Boot project and use it here on my machine.

All right, so here I have a simple application called HelloJPS.

going to say I want to bring in that dependency.

So that dependency is going to be my JPS Spring Boot Starter.

That's going to come from dev.danvega and the version.

Actually, this is going to be jet.jps as well. And then the version is going to be 0.0.1 snapshot.

So let's go ahead and refresh Maven, cross our fingers.

Hopefully everything gets pulled in, I don't see any errors.

If we go in here, we can see there is our starter.

We can see that the code is there.

And yeah, everything's looking good. So now what I want to do is actually use this in my application.

So in my app, I might create a to do controller.

this is a REST controller with a request mapping of that I need an instance of my GPS to-do client, right?

that through constructor injection.

I'm going to have all and all I'm gonna do is use that JPS to do client to find all of the to do's.

looks like it is, I can go into a terminal.

I can use a quick command line utility called HTTP pi whatever it is and say 8080 slash to do's and hopefully we get 200 to dos and we do it.

Now that is using the custom Spring Boot starter.

wanna like grab a list of to dos and use them for something.

I have an example of that.

if I just need some like dummy data to play with.

So I think that's it. Again, this was a pretty simple example of it.

This isn't like the best way to do it.

This isn't the most advanced way to do it. We got to learn how to walk before we can run.

there are probably ways that you can set this up a little bit different, project, having the code in another project.

But I wanted to include it all in one just for simplicity's sake today.

And also, there are probably some better examples that we could have done.

One example that I want to get into is I use Notion a lot.

And I've connected Notion to my spring apps before.

But I've done this in a very manual way.

like try to like figure out how to do that again.

And that would be another reason to use a starter, right? applications as like building blocks for bigger applications.

good use case for creating your own custom starter.

That's kind of one side of the thing. The other side might be just in your organization.

You have common ways of doing things.

you learned something today.

I thought this was really fun There wasn't a lot of great info outside of the docs out there on how to do this to keep going with this Let me know and we can come up with some other examples and even pushing it to like Maven Central is probably a good idea. So hey, I hope you wanted something new today, friends.

thumbs up, subscribe to the channel, and as always.