Benefits of Spring Boot based applications in a practical Hello World example

1. Introduction

Every, or almost every developer, knows Spring potential when thinking of how to resolve or develop a software solution, either for a web application or a background and/or scheduled process. One of the most recent tools of Spring is Spring Boot. Its main idea is that the developer only focuses on resolving the business logic rather than on configuring the necessary environment to run their application, as Spring boot does this for them. Furthermore, Spring Boot can be used together with other Spring solutions like Spring Cloud. In fact, Spring Cloud builds on Spring Boot. Let’s pick Spring Cloud Consul working with Spring Boot to describe how easy it is to manage an integration with another service in the cloud, in this case with a Key/Value Store feature of Consul.

2. Step by Step example

The idea of the example exercise is to list the current instances of people existing in a table in the database, in a console terminal. But its main purpose is to store the configuration to create the connection to the database in Consul as a key/value. Through the implementation of Spring Boot with Spring Cloud Consul to get this configuration and using such configuration in the bootstrap.yml properties file, Spring can take these values to establish the database connection when it creates the context. As a bonus, we use Spring Data JPA to get the example data from the database. This is another little example of how easy it is to integrate one more of Spring.io solutions with Spring Boot.

2.1 Previous consideration

The MySQL database server and the Consul server are installed in localhost environment and running.

2.2 Preparing the environment

To begin with, we need to create a database instance and a table with the example data. Besides, we have to create a java maven project and set the key/value in consul using the Consul HTTP API.

Database

Create a database schema called spring_boot_example, a table named people and populate this table with the data needed for the example:

CREATE SCHEMA spring_boot_example;

    CREATE TABLE `spring_boot_example`.`people` (
      `id` INT NOT NULL AUTO_INCREMENT,
      `name` VARCHAR(45) NULL,
        PRIMARY KEY (`id`));

    INSERT INTO 
      spring_boot_example.people (name) 
    VALUES 
    ('James'), ('John'), ('Robert'), ('Michael'),('William'),     ('David'), ('Richard'), ('Charles'), ('Joseph'),     ('Thomas'),     ('Christopher'), ('Daniel'), ('Paul'), ('Mark'),     ('Donald');
Consul
    curl -X PUT -d     'jdbc:mysql://localhost:3306/spring_boot_example'     http://127.0.0.1:8500/v1/kv/configuration/db/url

    curl -X PUT -d 'user'     http://127.0.0.1:8500/v1/kv/configuration/db/user

    curl -X PUT -d 'user654'     http://127.0.0.1:8500/v1/kv/configuration/db/password
Java Maven Project
mvn archetype:generate -DgroupId=com.mycompany.app -DartifactId=my-app -DarchetypeArtifactId=maven-archetype-quickstart -DinteractiveMode=false  

2.3 Taking action

We need to edit the pom.xml file to include all the Spring dependencies, create the Person class and do the ORM mapping using JPA, create the Person DAO interface in order to access the data, and add the consul and database configuration properties into the bootstrap.yml file, so that Spring Boot takes these values when it starts the application context. Finally, we have to create the Main class to be able to run the application.

Pom.xml file

When the pom.xml file is edited, the resultant content should be:

<?xml version="1.0" encoding="UTF-8"?>  
<project xmlns="http://maven.apache.org/POM/4.0.0"  
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>com.mycompany.app</groupId>
    <artifactId>my-app</artifactId>
    <version>1.0-SNAPSHOT</version>

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.0.RELEASE</version>
    </parent>

    <dependencies>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-consul-config</artifactId>
            <version>1.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-consul-discovery</artifactId>
            <version>1.0.0.RELEASE</version>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-consul-all</artifactId>
            <version>1.0.2.RELEASE</version>
        </dependency>
       <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
    </dependencies>

    <properties>
        <java.version>1.8</java.version>
    </properties>

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</project>  
Person class
@Entity
@Table(name=”people”)
public class Person{  
    @Id 
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private long id;
    private String name;

public long getId(){  
    return id;
}

public void setId(long id){  
    this.id = id;
}

public String getName(){  
    return this.name;
}

public void setName(String name){  
    this.name = name;
}
}
PersonDAO class
public interface PersonDAO extends CrudRepository<Person, Long>{}  
Bootstarp.yml file

We have to create this file in the resources folder and add the next content:

spring:  
  cloud:
    consul:
      host: localhost
      port: 8500
      config:
        enabled: true
        prefix: '/'
        defaultContext: '/'
        format: KEY_VALUE
  datasource:
    url: ${configuration.db.url}
    username: ${configuration.db.user}
    password: ${configuration.db.password}
    testWhileIdle: true
    validationQuery: SELECT 1
  jpa:
    hibernate:
      naming-strategy: org.hibernate.cfg.ImprovedNamingStrategy
    properties:
      hibernate.dialect: org.hibernate.dialect.MySQL5Dialect

NOTE: The url, username and password properties of the datasource are written as Spring placeholders annotation (${…}), which means that the value is taken from an external context, in this example, from Consul.

Main application class
@SpringBootApplication
@EnableDiscoveryClient
public class Application implements CommandLineRunner {  
    public static void main(String[] args) {
        new SpringApplicationBuilder(Application.class).web(false).run(args);
    }

    @Autowired
    private PersonDAO personDao;

    @Override
    public void run(String... strings) throws Exception {
        personDao.findAll().forEach(person -> 
        System.out.println("Person id: " + person.getId() + " - Name: " + person.getName()));
    }
}

3. Conclusion

Through this example we tried to prove how simple it is to create Spring Boot based Applications. It just requires very little configuration in order to be able to integrate cloud-bases and others services in the application.

The following are some other Spring Boot features that might come in handy:

  • Create stand-alone Spring applications
  • Embed Tomcat, Jetty or Undertow directly (no need to deploy WAR files)
  • Provide opinionated 'starter' POMs to simplify your Maven configuration
  • Automatically configure Spring whenever possible
  • Provide production-ready features such as metrics, health checks and externalized configuration
  • Absolutely no code generation and no requirement for XML configuration

More info