February 24, 2014 | Cloud Native, Microservices
Last year some of us attended the London Spring eXchange where we encountered a new and interesting tool that Pivotal was working on: Spring Boot. Since then we had the opportunity to see what it’s capable of in a live project and we were deeply impressed.
WRITTEN BY
Our project involved the creation of several independent microservices that provided functionality for consumers via REST/HTTP APIs. Most of them had to communicate with a data store, too. Each of these services had a single, well-defined function, for example handling common user data or dealing with webshop-baskets, etc…
Using Spring Boot, our average-sized service contained (excluding unit tests)
In exchange for that we got
After we got acquainted with Boot, it took one of us a couple of hours to create a new, fully functional, decoupled service from scratch.
To leverage Spring Boot, you need to set the spring-boot-starter-parent project as your Maven parent (Gradle is supported as well, we used Maven) and put some dependencies in your pom.
One of the great ideas in Boot is that it will import default configurations based on the contents of your classpath. If you want to build a Spring MVC application, just pull spring-boot-starter-web. You need messaging with RabbitMQ? Add spring-boot-starter-amqp; it’s there and it’s working. It is really that simple.
In addition, using the Boot starter as your Maven parent gives you default library versions for many commonly used Java libraries like core Spring, JUnit, Logback, Guava, etc… so you don’t even have to worry about versions. The flip side is that when you actually need a specific version of a library, you have to override these defaults and may encounter incompatibilities.
The example we are presenting is similar to the official Spring Boot quick start which it is a very good way to get started. We will add some comments on what is happening and start with a slightly different setup.
The first step is to configure Maven for Spring Boot. This means that you need to
Be aware that because Spring Boot is not yet released to production, you’ll need to set a custom repository (http://repo.spring.io/milestone) to pull all the dependencies.
In this example we are going to add two Java classes, one responsible for startup and basic configuration, the other is our MVC controller:
@EnableAutoConfiguration @ComponentScan("com.opencredo.springboot") public class HelloConfiguration { public static void main(String[] args) { SpringApplication.run(HelloConfiguration.class, args); } }
@Controller public class HelloController { @RequestMapping("/hello") @ResponseBody public String hello() { return "Hello World!"; } }
Please note the following:
And that is all you actually need. At this point you should be able to start this application from your favourite IDE, launching class HelloConfiguration. Then visit http://localhost:8080/hello which should result in “Hello World!” being displayed in your browser.
As we previously mentioned, Spring Boot gives an easy way of packaging applications into a self-contained executable jar file. To do this, just add the spring-boot-maven-plugin build plugin to Maven (you may have to add http://repo.spring.io/milestone as a plugin repository).
Packaging the project should result in the creation of two files:
The .original file is the output of the default Maven compiler, while the other one is the jar file enhanced by Spring Boot’s plugin. If you check the sizes, you’ll notice that the latter one is significantly larger (ours is almost 10 megabytes). The reason for this is that Spring Boot packages all the dependencies necessary to run the application into this single jar executable jar.
If you now start this (simply java -jar), you should see the same output that was in your IDE’s log window, and when checking http://localhost:8080/hello, you should see the same behavior.
The fact that Spring Boot pre-configures almost everything that you need for you is very useful when starting the development. However the time will soon come when you will want more control over what is happening. Fortunately it is quite easy to override these defaults.
By default Spring Boot will look for a property file in the package root directory called application.properties, this is a good place to customize your application. By Maven conventions, place this file into the src/main/resources directory so your build artefacts will be generated correctly. For example let’s set the contents to:
server.port=11000
This will cause the embedded Tomcat to listen on port 11000 instead of 8080. If you now restart your service, you should use http://localhost:11000/hello to get access.
Finding out what is given by default and what you can override is probably probably the biggest problem with Spring Boot at the moment. There is no comprehensive documentation about all the options, but the code in org.springframework.boot.autoconfigure.* packages is a good starting point. (e.g. server.port is bound to a field in org.springframework.boot.autoconfigure.web.ServerProperties as of Boot 1.0.0.RC3).
If you need more execution-specific parameter use, you can do it. The usual convention of the property overriding chain: defaults < property files < Java VM arguments is still valid, but Spring Boot will also give you Spring’s command-line argument property source: with double dashes (“–”) arguments when executing your application, you can specify property overrides:
$ java -jar spring-boot-example-0.0.1-SNAPSHOT.jar --server.port=12000
As you probably have already figured out, this will result in your webserver listening on port 12000 and your application available on http://localhost:12000/hello
Spring Boot actively supports the usage of Spring Profiles. First, to activate a profile, you can use the double-dash command line argument syntax: –spring.profiles.active and list those that you want activated. Additionally, you can name your property files in the following way:
application-{profile}.properties
And only those that match one of the active profiles will get loaded.
Regarding your Spring beans, you can rely on the @Profile annotation to work as expected.
When pulling a spring-boot-starter project as a dependency, Boot will declare the most commonly needed beans. For example, in case of a web project, you will get a DispatcherServlet without having to do anything (usually, you can configure these default beans with externalized properties).
In the majority of the cases this will be sufficient. However, if you want to have more control over these beans, just declare them as you normally would and your beans will override the ones given by Boot (in fact, Boot won’t even instantiate any of its default beans if you have an overriding bean).
Although meaning a slight detour from the general Spring Boot description, when talking about web applications built with it, we cannot leave the Actuator unmentioned. It’s a Spring Boot module that immediately gives your Spring-based web applications basic health check and monitoring interfaces. To use it just add Maven dependency spring-boot-starter-actuator.
If you now recompile and restart your service, you’ll notice that a lot more endpoints are being mapped (this is printed to the log during startup). Some of these are:
You can access/modify (or change completely if you wish) the behavior for most of these. For example, if you want to add a custom metric, just inject a MetricRepository in your business beans, and start using it, it’ll get exposed via the Actuator /metrics interface.
More details on the Actuator.
Although most features that Spring Boot gives you are extremely useful and work very well immediately, we encountered a few cases where a bit of caution is recommended:
Despite the fact that Spring Boot has not even reached its first production release yet, it was surprisingly stable and very useful. Even though there are a few caveats to be aware of, we didn’t encounter any issues that we couldn’t solve in a reasonably easy way. Given that we needed the ability to quickly get new services and modules running and we wanted to build them on a Java/Spring stack, it was the perfect tool for us.
This blog is written exclusively by the OpenCredo team. We do not accept external contributions.
Anthos – A Holistic Approach to your Hybrid Cloud initiative
Multi-cloud is rapidly becoming the cloud strategy of choice for enterprises looking to modernise their applications. And the reason is simple – it gives them…GOTOpia 2021 – Platform Engineering as a (Community) Service
Watch Nicki Watt’s talk on Platform Engineering as a (Community) Service at GOTOpia to learn what it takes to build a platform that is fit…