Enterprise Java with Spring Boot

Modularity in Spring

Josh Long
Broadcom
Enterprise Java with Spring Boot

Lesson Description

The "Modularity in Spring" 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 emphasises the importance of modularity in Spring applications. The separation of concerns is core to Java, and modularity at scale keeps applications maintainable. A pet adoption app is scaffolded to highlight modularity techniques. Initial classes for Dog and Vet objects are created.

Preview
Close

Transcript from the "Modularity in Spring" Lesson

[00:00:00]
>> Josh Long: We just spent a moment looking at messaging, which I think is, I hate to think that it's niche, I don't think it should be niche. I think it should be the prevalent standard, should be the way we think about building systems today. But admittedly, for the moment, it's not an everybody concern.

[00:00:17]
What we're going to talk about next I think is more of an everybody concern. Before you've ever gotten a bite across a network socket, you're going to have to think about how you structure your code base. And in a Spring project, which is, remember, Spring is Java and Java, say what you will about Java, but it is really good at building large code bases, right?

[00:00:35]
It's got a good strong type system, very fast compiler. Well, if you're not doing Graalvm, that is. And it's got, you know, modularity, it's got rigidity, it's got good information hiding in private privacy controls and it's easy to create a mess because of that. It's easy to create a very large code base with too many moving parts that don't play well together.

[00:00:52]
My muse is, as ever, Peanut and Prancer, the terrible, terrible dogs. So we're going to build a modular system to support adopting them. Okay, we're going to go to the lab again, we're going to generate a new project. I'm going to call it Adoptions. We'll bring in the Spring web support, we're going to bring in the postgres support, we're going to bring in the Docker compose support.

[00:01:08]
Although I've got a database that I've already got pre seeded with some data, so I'm not going to bother with this. But you could. I'm gonna bring in Spring Data JDBC, I'm gonna bring in the DevTools, I'm gonna bring in the Spring Modulus project, and I'll bring in GraalVM, I think that's it.

[00:01:25]
Maybe, yeah, that's it. Let's just call that, okay? And now, adoptions.zip, open in my IDE. And again, I wanna do this in such a way as to reduce the blast radius of change so that I layer things logically. So I'll create a package here called Adoptions and there I'll create a dog adoption service.

[00:01:43]
And this will be @service, @transactional. Why is it public? Right, this is an IntelliJ thing, right? I don't know why the ID insists on making things public, but they should not be by default. In Java, things are not public by default. You have to go out of your way to make them public.

[00:02:00]
And that's by design. So why intellij insists on adding that extra token, I'll never know. It encourages bad design. The result is that everything in your code is public by default, right? Which is, it's contrary to what we're trying to do with an object oriented language like Java, which has information hiding.

[00:02:16]
The whole point of information hiding is to hide information, right? That's one of the benefits there because it gives you that encapsulation. If you want everything to be in a big flat global namespace where everything is public, just use C. It's more honest. Do that. Don't do this, don't torture Java like that.

[00:02:33]
So we'll create a dog type here, string name, string owner, string description, okay? And I'll have my ID annotation here. I have my repository here, DogRepository, extends ListCrudRepository, okay? And I'm going to be connecting to a database. I've already got a database running locally, so I'll do spring dataset data source, my user password is Secret and then URL is jdbc PostgreSQL localhost my database.

[00:03:10]
Okay, so we have a method here called adopt void, adopt int dog id and we're going to pass in the new owner and that's going to connect to a database. Like I said, nice thing. In Intellij ultimate, you can click on this, click on that, click on that, Go over here, go over there, go over there, go over there, go over there.

[00:03:28]
Tables, dogs. Okay, so there's our dog, Prancer. This is our buddy that we talked about yesterday. He's a demonic, neurotic man hating, animal hating, children hating dog that looks like a gremlin, okay? And awkwardly, no owner, right? So our goal is to write a little bit of software to help remedy that situation.

[00:03:48]
And so we're going to use the DogRepository here, add that to the constructor, and we'll say this.dogRepository.findById. If the dog is present, we're going to update it by writing out an updated version of the owner of the dog, rather to the database with a new owner attribute there.

[00:04:05]
And so I'll then say dogRepository.save(), and so on, okay? And now I might just announce, hey, adopted this dog, okay? Updated like that. And then that. And now I want to test this out. I want somebody to interact with that service. So I'll build a controller and notice that everything has been packaged private.

[00:04:26]
It's not public. I'm just doing everything in the same package. You don't have to. You can do everything in the same package as separate classes and separate files. And that works as well. So, /dog/{id}/adoptions, void adopt, and it'll be a @PathVariable int dogId, and it'll be a @RequestParam, right?

[00:04:44]
An attribute in the request that'll get sent in. So that's called owner. And then we'll say dogService.adopt dot dot, okay? So there's my DogController, my DogService, my repository, and my entity in 50 lines of code, 50-something lines of code. Now let's try that out. Okay, I'm going to start this up.

[00:05:05]
Hopefully this will work. There's only one way to find out. Okay, it looks like it's good. So HTTP form post HTTP. Sorry, it's at :8080/dogs/45/adoptions owner=jlong, right? And remember, I haven't run that thing yet, but remember, owner is null for 45. His ID is 45, okay? Dogs 45 adoptions post refresh that.

[00:05:37]
And now the owner's JLong. So it's worked. Yeah, kinda. But come on, that's a bit of a contrivance, isn't it? That's a silly example. I mean, I wrote everything is in its place and everything kind of makes sense for what it's doing, but it's a lot of code.

[00:05:50]
Just update one little column, and one table, and one database somewhere, right? And yeah, that's pretty trivial. I get it, I get it. It's a bit of a contrivance. And it's not real, is it? In most organizations, in most jurisdictions, you can't just take possession of a live animal by updating a single column in a single database somewhere.

[00:06:07]
There's typically more process involved, right? You might have to schedule an appointment to see the veterinarian. Okay, so we're go over here and we'll create a new package here called vet. And then in there, the veterinarian is a doctor for dogs, so it's a dogtor. Okay, we should call it that.

[00:06:26]
And now I could, I could make this public. I could do that. I could say public void schedule(int dogId), and then `System.out.println("Scheduling for this dog ID"), right? And then I could use that dog tour back over here in my main code. So close that, close that. And down here, right.

[00:06:47]
Before I print out the confirmation, I could say dog tour. Schedule dog ID so I can schedule an appointment to have the doctor have the dog looked at by a dog tour. Okay, so now we go back over here, publish the same request. There you go. And go back to the command line.

[00:07:05]
Where's my Command line? Command five. Okay, you can see it says Scheduling for 45 and adopted this ID.

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