Spring Tips: Organizational Consistency in your Spring Boot Applications

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
a spring fans and welcome to another installment of spring tips in this hopefully very quick installment we're going to take a look at some ways to make your organization and your code more consistent and I know that's a particularly odd angle to purchase but what what uh what I find is and what we most artists have discovered is that constraints give you freedom right being forced to work within the constraints of a part of a particular system allows you more flexibility in other parts of the system and it frees you to think about the things that actually matter and so spring boot is really amazing because it gives you this this this impression of being completely free to do whatever you want while also providing ample guardrails right these guard wheels help you stay on the right path as you are as you are working on the code and as you're building systems and this is particularly important for large organization so what we're gonna talk about today are just some things that I find that are helpful to make it easier for people to build services and applications that that that scale right in the large in terms of people not in terms of like I mean they do scale in terms of API requests but that's not what I'm talking about I'm talking about as an organization can your software scale and so we're just talk about a few things that help you with that and I'm gonna start with some obvious things and maybe some small things that you haven't seen before okay now today I'm just we're gonna start by building a simple application demo okay and we're gonna just use spring boot 2.2 om3 I'm gonna bring in a few different dependencies so I'll bring in the configuration processor right there it is I'm gonna bring in Lombok okay and what else what else do we want I think that's probably it right so we'll hit generate seemed right to me yeah okay I'll do that just a very simple application nothing nothing particularly interesting here we'll open this up Desktop was hard downloads demo idea upon the next mm so we're building a brand-new application and we're gonna do something as trivial as possible we're gonna see that um I'm not actually demoing a particular thing I'm doing things you can do with spring so the first thing we're gonna do is gonna build an application that prints out a random number not a big deal but we can do it right so let's do that okay there it is okay make sure we have the latest and greatest here all right so we now have a very simple application let's say that we want to build an application that when it starts up it injects a injects a service that then you know number service whatever very simple very trivial obviously pointless some thing okay so when are then we're gonna have let's see void generate and okay whatever I don't think there's a I'm under no pretense about this being something you'd need to write but it'll demonstrate a few things for us so private final thread local random new or is it just thread local random dot get current date okay actually you would probably want to call that each time so you'd say okay there you go and we're gonna say thread local random dot int or next int okay what do use a bound okay so I'm gonna create a bound here and the bound let's say that's that's parametrize Abul it's something that we want to have specified when the application starts up and specify that here and it'll be something that we create in the constructor okay so it'll be a thing that we can inject your property and then there we go alright so now we return this and we'll say next okay good stuff alrighty so we've got now a very simple application all we're doing is specifying this bound why doesn't this seem happy oh no beans upside yeah there it's not a bean so we're gonna have to specify this we're gonna provide a value okay so it's gonna come from a property somewhere something is gonna configure this bean with a value okay so I'm gonna I guess I could put it in a property and a string but one thing that I want is I want this thing that produces a value two to use a property to look up that object so a very common approach here is to extract that out let's say I wanted this speed I wants to be numbers dot you know random dot bound okay I better yet keep a simple just numbers dot bound so that's a property that I'm expecting from this spring framework environment and that means that I could put it in the environment literally as an environment variable I'm just going numbers underscore bound it cetera it could be here equals ten I can do whatever one but this is a string right you know your hope you're hoping that when you extract this from the environment that it is actually an int and spring will have no problem coercing it but you don't know all right there's no guarantee there and also when you when you type this there's no you know there's no sense that this property exists you don't know if it's there or not and so very common thing to do is to create a configuration processor sorry is to use the configuration processor to define configuration properties so let's say class number properties okay and I'm gonna say private int bound so we'll just use Lombok here good and we're gonna say at enable configuration properties number properties doc class okay so there we go and what we're doing is we're telling spring hey I want to create an object that has these properties bound to things in the environment so I'm going to say that this is gonna use the prefix called numbers so it'll say numbers dot bound so now when spring starts up sooner when I compile the code let's all do here on invoke the terminal and do a maven clean install or maybe clean package okay good stuff so there it is so now notice that the the gray the highlight behind this has gone away alright um make sure we're all on the same page here to make this font a little bit bigger there we go 6 so you can see that South numbers don't bounce equals 10 and you can see the the property is now defined in this object this object is using a Lombok so it has getters and setters and all that stuff right I can inject number of properties and I got a gotten getters and setters so all that is there it's based on this property I can now just inject this here as an object it's a bean right spring is actually gonna create a beam of this object and so rather than having this string the reference thing here I can say NP and then I'll say NP dot get bound right so there we go I've done a couple things to have created a number service completely pointless and I've created a some properties to define that number service all right so now I can inject this number service somewhere and use it okay so number demo and I'm going to inject the number service here create a constructor event listener application ready event public void run and then this dot number service dot generate random number and I just want to log out the data so I'll to add component at mama for J okay and item number alright I say a long to info random number equals remember that is a completely pointless demo I think we can agree it's absolutely fair to say that but what have we done we've created two objects when is the configuration properties that hold properties from this property file so now let's say I want to type this again well now if I go to the property file application of properties and I hit control space that configuration processor that we added to the bill here this thing here a spring boot configuration processor that's actually Germany an indexed file in the index file it's being used at runtime by the IDE it's an index file that has JSON and four it's basically a JSON structure that gets stored in the build and that is being used by the IDE to in assist it in Auto completing for example this right I can say numbers pound equals ten and you can see when I command click on this when I highlight and hover over this and command click on it it takes me to this object alright navigate to this configuration properties object so it knows about this object and the mechanism that we're doing this we built this generically it's in spring boot proper it's not a feature of intelligent only so you can use it NetBeans you can use it in the spring tool suite so it's just a very good way for developers to be very easily consume your application you can consume configuration now in this case I've kind of here's my if you will with my client the thing that's he using the infrastructure the service and the properties that I've configured and here's the actual configuration itself the thing that I want fine I've got the producer in the consumer in the same code page nominally these things are you know maybe they they live in the same code page but they might even just live in separate packages but let's suppose that I actually wanted to reuse this number service and this configuration across multiple jars for whatever reason obviously this is a demo just indulge me okay so if I want to reuse this I'd like to extract it out into a library okay so let's go back to the initializer and we're going to create a numbers okay and we're gonna create a numbers auto-configuration okay so here we're gonna add we're gonna have Lombok and the spring configuration processor and that's it we're gonna hit generate and all we're doing is we're creating a new jar and we go back here ueo numbers Auto configuration okay and so what I'm doing is I'm gonna I'm gonna this is a Springwood app but I want this as a library so what I'm gonna do is I'm gonna delete all that okay your package sorry package numbers I'm gonna create eight numbers auto-configuration okay numbers out of configuration and it's going to be a class that spring boot will read up will start up and in that configuration we're going to register a beam of type number service okay so we need to have this here okay and we don't want to rely on classpath scanning so I'm gonna take off this service annotation there and I'll just do at beam okay now the same problem I need the pointer to the number of properties itself okay so I'll pass that in all right so now I've registered this beam to a configuration and now what I want is for this configuration to get registered whenever somebody has this library on the class path so this is easy this is I'm gonna go to the resources director I'm gonna create a new directory here called meta in and I'll create a new file in there called spring net factories and here I'm going to use an attribute this is a service loader mechanism in spring okay so this resources meta F spring that factories is going to result in this you know it's gonna look up these files in all the different jars it's gonna find this attribute and here I can just list any auto configuration that I want it to care about so I'm gonna create this one I'm gonna copy the reference to this go to my spring two factories and there we are okay so now I've told it about my numbers Auto configuration and now I want to consume this dependency in my code right so I'm gonna actually what am I gonna do I'm gonna get rid of the stuff that makes this a so-called fat jar and application I'll get rid of all that I don't want that I'm gonna leave in this stuff I'm gonna leave in the spring boot starter now normally in this case you wouldn't want your starter your dependent to your auto configuration to in turn specify the version of spring boot it shouldn't manage that right it shouldn't insist upon that so you might actually this case want to bring in the spring boot bomb the bill of materials that way you're actually bringing it in as another dependency it has the effect of level setting your dependency versions without having any effect on the tree being used by the people who are consuming your library but I'm gonna just keep it simple because I don't have to specify things like the compiler plug-in and all that stuff so I'll leave this all here but there are there's good documentation on the specifics of what you would do here so spring food starter wiki how to you know there's a there you go spring boot starters so you know these are starters let's see creating out there you go there you go so you when you create starters there's two bits right there's the actual auto-configuration that's what we're doing right now and there's the starter dependency but when you use when you create your own starter do not start your module names with spring boot so you know that because that way it's easier for people who are using maven that way they don't discover your thing wax and they don't actually autocomplete spring boot - your API when we might do the same thing in the future right so that's a that's a very convenient thing right okay so we're gonna we're gonna avoid doing that right now we're creating an auto configure module right um actually I named it Auto configuration let's just name it Auto configure okay so Auto configure and I'm gonna call this numbers okay or spring tips there you go talk numbers Auto configure and so this has the dependencies that we want we've got the configuration processor okay we need the spring boot starter dependency and that's it right and that's I think the basic setup one configuration metadata okay so we're going to call this the this is the Auto configure dependency right this is the dependent it has an auto configuration the reason that there's a distinction between an auto configuration jar and a starter is that the starter brings in the dependencies that are required to make this work whereas the auto configuration has the code so in this case in theory I could create more dynamic auto configuration let's say that I have let's say that for some reason we're on a JVM that doesn't have thread local random okay so I could say okay conditional on class thread local random dot class and what that means is that this configuration would only activate if that type was on the COS path that would actually stop this from being registered right it will stop the configuration class etc from being registered and that's very useful you can create very dynamic application so you can say if this library which you are testing you know whose presents are testing for by by virtue the fact that this class is implied by the dependency if that classes on the library then register these beans okay so in our code we of course the classes on the library class path but they don't need to be right let's what's a what's a silly example that I can bring in let's say that I register a dependency here using spring web flex okay so I'm going to use the reactive spring boot starter web flux okay and I'm gonna make this scope optional it's true okay so I'm bringing this dependency it's compiled against my code and now I'm gonna register another beam I'm gonna say at beam router function okay or maybe it's scope provide it there you go okay let that build maven okay we start come on writer function there we go server response Oh okay so what I'm doing is I'm creating a functional reactive endpoint and it'll just serve up the number dot get number new handler function and I'm gonna use this number service here okay so I'm using the reference to that si server response dot okay dot sync body and s dot generate random member okay and we can actually do a single pin map number all right so there we go we've got now a singleton map we've got a random number add this there okay so now I've got a random number now do I want this functionality all the time maybe the users of my library won't have Spring web flex on the class back so I could say conditional on class you know what's the thing I guess router function my insider function to type that may not be there so this beam will only be registered if this type is true and we're not assuming it's true so if you install if you use our dependency numbers Auto configure in your code then this won't this won't be activated by default unless you also bring in spring boots starter webhook so let's try this out let's go to our console here okay may even install let's see which file all my tests you should definitely tests but uh I don't have time even they even clean install all right so that's now installed now I want to reuse this functionality so let's go see what happens if I bring them in to my other application over here I'm gonna go to my build and bring in that auto configuration okay good so there's this and the version is probably the same one is up here right because I don't think I've changed it right so there we go okay so there's that so now I'm bringing in the auto configuration I changed the package when I wrote this code so let's make sure we comment out that type goody may even re-import number service there it is so copy a reference to this package numbers import right did I make the type not public I think I did Oh No so number auto-configuration okay of it okay good stuff for now we install all that go back to here there you go the type in our public so now I can inject the bean right and I'm not I don't configure there's no place in this code where I'm actually configuring that dependency why is it still unhappy is this method not public Oh Josh don't take the lazy way okay there we go so now we go back here there we go so now it's public as well so now I can run the same code without having to auto-config without having to configure those dependencies now if Emily wants to reuse this basic behavior all right no loose that's not found router function Oh so it's trying to load this because it has the class in the method what I should have done is I need to cordon this off into a nested configuration so I can say static class web config and I that way it's not gonna it'll load the outer class and not the inner one right so public static there we go and I want this to be only loaded they want the new nested class to be loaded only if this typewriter function is on a class path okay should we start okay so there you go it started up and there's no error because it didn't try loading the web endpoint but I want that web endpoint and so this is where we get into the concept of a starter so it's you can see that I have two modalities in my auto configuration I've got the default modality which is like the set of beans at a run and evaluated by default when you start the application and I've also got this web but modality this web sort of behavior that runs only if there's a certain package on the class path or something module on the class path and so I want to be able to support or export that functionality to the world and the way you do that is you create your own starter dependency so I've got an auto configuration dependency you can create a starter dependency as well and a starter dependency just brings in the things that you want to be able to activate certain bits of functionality you can see that we do this in spring boot all the time so we say spring food you know what's a good thing um spring boot starter web right that jar is otherwise basically empty there's nothing in it right the the jar itself doesn't have any functionality except for a maven palm this palm intern specifies you know that we need these libraries to make up the support for web flex so it brings in spring boots starter brings in the web flex support etc etc etc so you can create you own maven starter and you you know make sure you don't name it with spring boot it has to be like you know you're a coop ID and then for the artifact of the numbers spring boot starter not spring good starter numbers right and that that would bring in only the correct versions of the dependencies that you want so again you might use the maven bomb there the maven Bill of Materials dependency and you might say I want to have numbers Springwood starter web right and so that would be the that would if somebody brought that in there's no Java code in there it would only have the effect of transitively forcing me even to add spring boots started web flex to your application so that you know and it would also bring in the numbers Auto configure but bringing this Auto configuration and it would bring in spring boots or web flex so that you would have everything you would need to run this in configuration class right so let's we can kind of shortcut that process we can actually go to our demo and explicitly add in web flex to activate that functionality so there we are now we've done the same thing now that condition will evaluate to true we can restart this okay so you can see that the applications up and it hasn't shut down it hasn't stopped because it's still running because we created an in point so I think it's called number number there you go okay so we created a rest endpoint dynamically based on Auto configuration and that we didn't have to write any code on the client side as we use that to do that so this is this building of a starter building of Auto configuration building of Auto configure modules this promotes reusability across the organization it's a very useful way to ensure that you have consistency across your different teams and in the organization you might extract out things like your security configuration into a separate jar you might extract out things like logging and auditing and things that you have want done a consistent way across the organization right maybe the way you've configured connection pools for your particular legacy db2 instance or something like that whatever right though these things are all sort of up to you to to to decide okay now the left via the work I've done so far covers I think we've looked at a lot of different things here and we've looked at a couple things we've looked at the auto configuration we looked at building your own auto configuration jars and starters we looked at all these kinds of things that you could do for a while the next I think the logical next step a lot of people don't take is that you can actually build your own spring initializer right so let's say let's say that I had gone through the process of building a starter which is just as I say just a maven pom that brings in your auto configure and it brings in your your your the prerequisites required from the ambient you know dependencies out there spring booster web plugs and so on let's say I'd done that now I want to have my own dependency on the initializer right start out spring that I oh well you could you could work with us and - a very very lengthy process we can add your dependency here if you've established there's a large community that it's open source that I get to consistently maintained but if you just want to have your own initializer for your organization so start that your organisation that IO but we can do that right and you can do that yourself you don't need anything special from us so you can go to github.com spring io and you'll see that spring an incisor is actually a generator first of all it's an API that's represented by this project here spring IO initializer and then it's a and then there's a particular customized implementation of it called startup spring IO that's this thing here and that's the start client in the start site and this is actually the integration with that generator that generates is generic it doesn't have to be used for Springs and the user interface doesn't have to look like ours right it can and if you want to talk like ours you can clone this this is Apache 2 license to open-source please use it and and so I've got this clone to my local machine here right SSDI start dot I shouldn't you know I should show you this nope there you go it's start client and start site and I even have it open here in my IDE okay and so what you need to know is that this is the this has the two project start client start site and the only thing I've done is I have gone and I've created a I've gone to this property file called application that yamo an application that llamo is where we customize the look and feel of the generator it's actually where we provide the different dependencies that belong here right so you can see this is actually a fairly deep I mean hundreds and hundreds of lines of llamó that configures all the different jars the check boxes and then the Bill of Materials dependencies that are assumed there all that stuff right so Java versions the maven the Gradle all that stuff that could be specified we specified here right and there are customizations as well you know Java code that maybe you don't care about maybe you don't want you can you can get rid of them you can add them you can remove them so for example we have custom you know there's certain things that require other work it's not just as simple as choosing a checkbox so for example we customize the Gradle build if you add dev tools for example or if you customize the maven build if you had the dev tool so some things are not there there's not a one-to-one correlation for example so these are these are things that get added to your build but are not quite as simple as just taking the configuration that property file and then then emitting a dependency right it's actually requires a build materials it requires that other libraries be there or whatever and you can express all these things through these different customizers okay so I I don't want to we could we could and should do a whole episode on just how to customize this but suffice it to say most of your work will be here so what I've done is I've gone and I've created a arbitrarily named bootiful section okay for a fictitious library called go long and the idea is called go along now I'm gonna actually change this so we've got go long lips we've got our auto configuration you shouldn't put your auto configuration here it should be the starter dependency okay but just so we have something we can look at let's try it out so numbers auto-configuration st numbers auto configure okay taking all that taking that to here and okay so it's ID GUP ID is st and the this was gonna be called here and snapshot okay random alright so there we go I've got my random number dependency added this to this in your sizer and I'm going to customize I'm gonna run it by going to the start site on the command line here so I'll say terminal CD start site maven spring boot run okay and now if I go to localhost 8080 oh did I have a no let's just assume I have a release version here 1.2 that I would release okay oh I've got something else in port 8080 of course I'd close that one out or that again there we go so it's down the metadata the first time there we go so now there's our to that oh we can say I want to see all the dependencies and there's our new section bootiful go along if I hit generate hit update dependencies that gets added to this and then hit generate and you can see that's downloading a new zip file what do we call this we called this is this demo so open this one and what is this file look like all right so there you go you can see it says STI numbers auto-configure the issue of course is that I haven't specified the version it isn't it is assumed that you have attached to your dependency here a bill of materials dependency that would then get registered automatically in your dependency management section so the version would be specified in that Dannette bill of materials and so you should also create one of those a bill of materials is merely a dependency that has a dependency management section that looks kind of like like our build materials for spring boot right we've got one as well so there's documentation on how to do that as well but you can see how this would work right you dependent you add this and you then tie that dependency here to a let's see the bomb all right so you can see that these demands sometimes these dependencies reference a bomb name right and the bomb is a thing or it's the bomb dependent dependencies different definitions okay Hegel and just eyes are bombs right so if you want any of the azure dependencies they will specify that my bomb is equal to Azur and then when that gets specified then this gets added to your maven build it'll say I'm gonna automatically add in the dependency management section call Microsoft Azure as a zero screen blue bomb Azur that version and if you're using spring boot 1.5 for 22.0 then you'll get the azure bomb Oh to four and if you're using spring boot to that one oh release then you'll get to that one 2 etc so this logic tells you no spring Buddha's are automatic is smart enough to know okay you want the version of this bomb that matches the version of spring boot and we expect that to mean be maintained and you should do the same for your organization okay so with that we have our own custom Edition sizer we can customize this to our hearts content of course and you can reskin it and change it and so on and by the way we have people that work on this full-time right there's a team of people that work on the initializer so we're always keen on getting feedback if you want want to contribute back if you have a big idea it's an open source project we're happy to hear from you one thing you know this is a pretty trivial demo I could I think we can all agree on that same thing for my um same thing for my auto-configuration right but my auto-configuration I've customized it I formatted it I'm using IntelliJ right so if I do this let's just get rid of all this you know claps it all together like that okay there's my there's my formatting it does that it good formatting do we appreciate that I checked in the code like this with no spaces all right just like that I used VI or something like that and I didn't I didn't care about spacing I don't think that's very good I don't think that's very nice I don't think people in like that so I might do command alt L on the Mac for IntelliJ and command hotel will automatically format the code but what about the people using eclipse or NetBeans what about their code for matters what if they then we format the code to be to their liking in that environment is that gonna be good do we want that result and they want to check that in that means that when somebody looks at the code the only thing that's gonna be different from one environment to the other is the formatting which is a not great thing right it's gonna give you the perception that something has changed when in point of fact something it has not um and what about my my choice of lines here I've rapping like this right and I want things like that you know I want more types of annotations on the same line do you like that is that you know does that make you feel better about your trust in me your confidence in me that I've done this to your code so again you can't you know the nice thing about spring mood is that there is no particular IDE requirement it's just anything that supports debate and may even or gradle and as a result you have full latitude in doing you know complete latitude do you know using whatever tolling you want and you're sort of up to the whims of whatever ID the person editing code is using at that point right and so one thing that we want is for people to not focus on this kind of stuff just not worry about it so there's a nice tool that we developed for our own uses and which I Josh I'm also using for my books I used it for the reactive spring book just extensively so all my code uses this tool it's called spring Java format so okay spring Java format and it sits under spring io spring - Java format and in order to use it you just add this plugin to your build okay actually better yet let's do this okay so I'm gonna go to my build in my auto configuration here and I'll go to the build section and again you might have an organizational dependency that requires this get added to automatically to all the builds okay so we'll add this here cool so now we've got spring out Java we've got a Oh spring Java Foreman spring down for me even plugin and we go here and now let's just try and do it maybe in clean package on my code let's see what happens look at that it wouldn't even compile right it's upset it says spring you have to run spring Java format apply because these things don't match the formatting expectations of the organization of my project so I say maven spring Java format bye okay now let's go look at our code all right there it is there you can see it's been reformatted the way that the spring boot team uses for their code right now of course I don't like I still don't like that route is on the same - get right so you can do that right and this is you got wrapped in another line so that might be a clue to you and me but this should be extracted out into a a lambda maybe or method reference or something right yeah do what you can to make that code easier because you're at the whims of this reformatted so let's now see okay body so do I like that and my okay with that let's see what happens well it's actually in the idea isn't it okay so you can see it got wrapped to the new line but it's better all right so you you can see that because I did this it was forced to preserve it on the next line this got wrapped back so now I can have that there one more time okay so you can see it does a very good tuck behind the scenes this engine is using the Eclipse format or at least I think it was used it was at one point and so we're actually using the Eclipse formatter and we're formatting our code in a consistent way so now there's no question about what the right formatting is there's just one kind of formatting let's just agree tabs spaces whatever it's already taken care of for us don't worry about it just work on the code that matters to you all right and it'll actually break the build so you know it forces people to get in the habit of applying maven spring Java format clone and apply right so now all things being equal assuming everything else is valid I can do maven clean package and my my my build is correct let's say I go here and do that and that now what happens right it's telling me this file no longer matches formatting expectations so we do maybe in a spring dome format cleaning package that I like to do that because that makes it so that when I test my local code I format at first then I run the tests and that way if it passes its passed everything and I can just commit it and it goes to the CI environment okay so there we go we've looked at a number of different things you can use to ensure you've got consistency we didn't get a chance to look at the details of creating a starter creating a bill of materials dependency that's well documented in the documentation there are wiki's and things like that but but you should know that that's the thing you should do that's what I want to know because then that lets you disseminate your your dependencies throughout the organization and one great way to do that is through the spring and initializer and this finish size allows people to access consistently your auto configuration remember you can specify that certain dependencies be added to all projects generated by organization so maybe that security auto configuration that we that we hinted at earlier maybe you have that as a required dependency every project generated on your custom spring initializer must have this dependency just like the tests libraries in spring boot are automatically added no matter what there's no way to opt out of that right this can help ensure organizational standards it helps get ensure consistency you can also customize the maven build you could add this maven spring java format plugin for example or you could you can make sure that all the projects are seeded at a particular parent dependency instead of arms right so you can do some really interesting things and now you have a central place to do this you could also add support for creating you know Cloud Foundry files or docker containers or whatever you can add the Aven Jib plugin right lots of good options I hope you'll I hope you'll give all this stuff ago I am I think all the stuff is pretty cool I don't know how many people know about the spring Java format plugin I really like it it just it's one of the nice things about go the gold language is that there's a something called go format geo fmt and it just takes away the pain of like is this the right way right Python is very sensitive to space as well and it just takes away the pain of like is in tabs or spaces who cares just write softer let's get it to production don't worry about that right it looks the same it works the same the the Maven spring java format plugin has very little in the way of opportunities from reformatting or for customization it that's the whole point it is it is to be said it is to be the house style right it just takes away any discussion of is this the right way let's just focus on just writing software right let's not fight about this data or the the rest it's arbitrary all right thanks everybody thanks so much for watching I hope you got something out of it and as usual we'll see you next time you
Info
Channel: SpringDeveloper
Views: 17,189
Rating: 4.9571428 out of 5
Keywords: Web Development (Interest), spring, pivotal, Web Application (Industry) Web Application Framework (Software Genre), Java (Programming Language), Spring Framework, Software Developer (Project Role), Java (Software), Weblogic, IBM WebSphere Application Server (Software), IBM WebSphere (Software), WildFly (Software), JBoss (Venture Funded Company), cloud foundry, spring boot, spring cloud
Id: D33awJnlhWg
Channel Id: undefined
Length: 48min 39sec (2919 seconds)
Published: Wed Jun 05 2019
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.