Enterprise Java with Spring Boot

Spring Boot Features

Josh Long
Broadcom
Enterprise Java with Spring Boot

Lesson Description

The "Spring Boot Features" Lesson is part of the full, Enterprise Java with Spring Boot course featured in this preview video. Here's what you'd learn in this lesson:

Josh transitions to Spring Boot, which provides the same expressive configuration as the Spring framework, but with useful defaults that eliminate unnecessary boilerplate. Dynamic autoconfigurations are discussed. Environmental properties and Spring's event API is also demonstrated in this lesson.

Preview
Close

Transcript from the "Spring Boot Features" Lesson

[00:00:00]
>> Josh Long: But now let's look at Spring boot. What does Spring boot do? Well, remember I told you about how there's this configuration mechanism, this convention over configuration. Spring boot gives you the best of both worlds. It gives you the ability to create as expressive configuration as you want, just as I just did with all those different objects.

[00:00:17]
But it gives you some defaults, some useful defaults. So here I've got my service, my customer service, right? Just as before, nothing changed there. Got my LoggingBeanPostProcessor, right? And I've got my public static void main spring boot application. Where's the database? Where's the schema initialization? Where's most of it?

[00:00:41]
All that code I deleted, I don't need it anymore. So if you go back to the test, the test also gets a little bit easier cuz now I can use spring boot test instead of using SpringJUnitConfig. So the same basically, and also I'm using this nice extension to capture the output, this is standard out and I can do assertions against the output there, right?

[00:01:02]
So let's start the Spring Boot application. And you can see the Spring boot application has very importantly, very good ask get work banner as get work is key to successful production deployments. It also has everything else, shutting down customer service, the logability, all that kind of stuff. So everything is the same as before, but I wrote much less code.

[00:01:25]
And the reason that's true is because I have auto configuration. The auto configuration is the key to spring boot. This is why it's so consistent in large organizations and small. If you wanna get something up and running out the door in as few lines as possible, there's nothing more concise than your typical Spring Boot application, right?

[00:01:44]
I built an application that talks to a SQL database, has observability, is production worthy, has a container. And I just went to starts out Spring I.O. and I wrote six lines of code or whatever it was earlier, right? Ten lines of code. It's very, very concise. But it scales, that's the difference.

[00:01:58]
That consistency scales and the way it scales is through this thing called auto configuration. The auto configuration works, when spring boot starts up, it looks on the class path and it finds this text file called spring.factories. This is what makes Spring boot, Spring boot and everything else Spring framework.

[00:02:15]
So you look for spring.factories, this is a service loader, okay? Spring will find this class in the meta inf directory of your code. Where's my go over here, where's my target? It looks for the meta inf/. Meta inf spring.factories. It'll find this class and it'll find a key followed by a common delimited list of class names.

[00:02:43]
And these keys get used for different lifecycle pieces. There's another file that it looks for called autoconfiguration imports Imports. And this file lives in spring boot jars. You can see this one lives in metainf spring Org springframework Boot auto configure Autoconfiguration imports. That's a text file. The name of the file is called autoconfiguration Imports, right?

[00:03:11]
Actually, no, it's called org spring framework Boot auto configure Auto configuration dot imports. And it's just a long list of Java classes. These classes get evaluated when the program starts up. So if you look at rabbit auto configuration for RabbitMQ, you can see it's got a lot of red here, right?

[00:03:28]
Look at that. Somebody I forgot about this class. This rabbit auto configuration is a configuration class, it defines a bunch of objects. But it has these tests, these tests, these conditions. This condition says run the RabbitAutoConfiguration, but only if there is a Rabbit template.class on the class path and only if channel class is on the class path.

[00:03:50]
It's like an if def macro in C, right? But it's happening at runtime, it's when the program starts up. So we, we add the body of this configuration to all the objects that are in play, but only if this type is on the class path. If the library is on the class path.

[00:04:06]
If it's not there, then don't bother because we would surely get a no class def error or a class not found exception or something like that. So this is very, very dynamic. What it means is that if you wanna have a default experience, you go to start spring IO, you choose some of those starters, those checkboxes that I showed you earlier, those over here.

[00:04:25]
If I go here, if I choose web, that spring web is gonna give me spring boot starter web, that's a starter. These starters are packaged with auto configuration. You just add that to the classpath and it automatically runs a web server for you and it installs spring MVC for you.

[00:04:45]
And it sets up the servlet stack and it installs JSON marshalling and XML marshaling and form handling just by the presence of the build. I've done nothing to the code, right? Nothing has changed to get all of that. That's because of the presence of these auto configured starters, that's very, very powerful.

[00:05:01]
Now because these starters are smart enough to be dynamic, there's also other conditions. I've got these conditional on missing bean. These conditional on missing bean say create this object, but only if the user hasn't provided the same object themselves. So if I were to, in my own code over here, create a bean of type blah, right?

[00:05:22]
It's gonna fail cuz I don't have that type in the classpath, I don't think. I do. Why do I have that in the class path? Well, whatever. The point is, if I did this by myself, then spring boot would defer to me, it would not bother creating this one for me.

[00:05:34]
So even though it provides one, it provides this one right here, it's a bean method, just like we saw in my own code back over here. This is an embedded database that I've got a bean method on it. If I didn't provide this, it would give me a default one, but if I do provide it, it backs away immediately.

[00:05:49]
So this is a framework in the sense that it's open for extension, but closed for modification, right? When we say closed for modification, we mean you don't have to fork Spring to change the way Spring behaves. You can, it's open source, patch, it's licensed, be our guest, but the point is, you don't need to, right?

[00:06:05]
These are all little cogs in the machine and you can swap them out the whole system. You don't have to unwind the whole stack like you do with Rails to change one little part of it, okay? Okay, so there's lots of other conditions you can do conditional on missing bean, conditional on class, conditional on property, like a property in the environment.

[00:06:22]
You can look for all sorts of different conditions that make these dynamic auto configurations very, very, very powerful. Okay, so back to Readme here. So now we talked about configuration before. When I talk about configuration, it's a little confusing. I mean, there's Java config, which is the class that has the bean methods, and there's also these properties, right?

[00:06:46]
We talked about that as well, I just wanna reiterate that you can get access to various properties in Spring that come from the environment, right? So this environment thing is a dictionary, it's a key in value dictionary, and it gives you access to properties that you put in your application properties file into D command line properties into environment variables, into things that are in HashiCorp vault or your Google Cloud's vault or whatever.

[00:07:12]
All these different things where you can source keys and values, they can be added as a property source to the Spring framework environment. And then that Spring framework environment can make those things available to you for Injection directly like this, beans, whatever, or bound it to a Java object like this.

[00:07:30]
So property configuration, beans properties. So here's the configuration, property configuration, etc. Any questions on this? Why does this matter? Because one of the easiest ways to impact the behavior of the program is to set a property. So you need to source them from wherever you want. Environment variables, property files, application YAML, application properties, d arguments, whatever.

[00:07:54]
When they're sourced, they're available via the environment. You can get them as values injected into various places, or you can have them bound to Java objects like this. I'm binding beans message to a strongly typed object that I wrote called beans properties or beans properties and the prefix is beans and the message the key is called message.

[00:08:16]
This mechanism right here means that if I want a strongly typed carrier for those configuration values that the user specified, I can just inject bean's properties and anywhere in my code and I'll get it. So that's what I'm doing here. This test is getting the same key directly from the raw environment, injected as a value or bound to a type safe thing, but the result is the exact same value.

[00:08:38]
In all three cases, we're expecting it to be hello world. If I run this, the test is green. It's not much to see. The point is, if I change, if I set up an environment variable or a property on the command line dash d, that'll override this inbuilt value.

[00:08:59]
Right now it's sourcing that value from here. So far, so good. Events Finally, Spring emits a lot of events. These events tell you how the application's behaving the lifecycle of various things. But it's not just pure infrastructure. It's like if you're using spring security, there's an event when somebody authenticates these events get dispatched to any component in the spring context that wants to listen to these events.

[00:09:25]
So here I have an events application, public, static, void, main I've got atomic thread safe variable to increment and I'm incrementing the variable. Whenever the application is ready, I have an event listener. I'm saying I want to listen for the event called applicationready event. I have another event when the context is refreshed and when somebody publishes a spring is awesome event, right?

[00:09:49]
So you can create your own events as well and you can publish those. And these can be any component anywhere in the code base can have event listener and a method. It can be called whatever on foo it doesn't, you know, or just spring is awesome event, you know, whatever you can call this method whatever you want, but as long as you have the type of the event and the parameter.

[00:10:07]
The other way around, the other way you could do it is to do Spring is awesome event.class and then don't do a parameter. But that's only if you don't care about the event type itself, which I do in this case. And all I'm doing is for each of these three different events, these are all distinct, right?

[00:10:23]
I'm gonna call this register method, I'm incrementing the counter so there are three events we should expect then, the counter will be three. I said, you can also publish your own events, so application, event, publisher, I'm injecting that. I'm gonna publish event called Spring is awesome event, and it'll get dispatched to all the components in my context, which in this case is just this one class, okay?

[00:10:44]
So if we run this. Here we go, and we should see that the value is three cuz we've got three different listeners. All right, there we go, that's events, we're gonna see events a lot. Events are how you communicate state from one system to another, from one component to another, from one module to another.

[00:11:03]
They're useful for hooking into things like, okay, the web server is initialized, I have a port. Now what? Right after the web server is initialized, I need to start warming up some cache maybe. Or I can hook into somebody's authenticator, or there's been somebody that didn't authenticate, they had an authentication failure, or a customer checked out on the shopping cart, right?

[00:11:23]
You can asynchronously integrate things into the lifecycle of these applications by publishing and consuming events.

Learn Straight from the Experts Who Shape the Modern Web

  • In-depth Courses
  • Industry Leading Experts
  • Learning Paths
  • Live Interactive Workshops
Get Unlimited Access Now