Java Spring Boot Getting Started
Nov 4, 2017
5 minute read

Part 1: Basic set up

Steps inspired by spring boot getting started guide.

Add some basic dependencies and Java file to return Hello world!

See the code on github.

Part 2: Using spring boot

Typical project layout

com
 +- example
     +- myapplication
         +- Application.java
         |
         +- customer
         |   +- Customer.java
         |   +- CustomerController.java
         |   +- CustomerService.java
         |   +- CustomerRepository.java
         |
         +- order
             +- Order.java
             +- OrderController.java
             +- OrderService.java
             +- OrderRepository.java

Where Application.java declares the main method, being the app’s entry point, like so:

package com.example.myapplication;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;

@Configuration
@EnableAutoConfiguration
@ComponentScan
public class Application {

	public static void main(String[] args) {
		SpringApplication.run(Application.class, args);
	}

}

Reference: Locating the Main Application Class.

Configuration

Favour Java-based configuration classes over XML.

Note that you can mix and match XML and Classes. Loading XML-based config via @ImportResource.

Reference: Configuration Classes.

Gradually replace the auto-configuration with yours

It could be handy to start with auto-configuration, while seeing which config is applied using --debug when starting the app like so:

$ java -jar myproject-0.0.1-SNAPSHOT.jar --debug

You would need to use the @EnableAutoConfiguration or @SpringBootApplication on your @Configuration class.

@SpringBootApplication is equivalent to @Configuration, @EnableAutoConfiguration and @ComponentScan together.

Reference: Auto-configuration.

Developer tools

Check the spring-boot-devtools module! It provides useful things like automatic restart, LiveReload, and Remote tools.

Reference: Developer Tools.

Part 3: Spring boot features

Application Events and Listeners

Events are sent in the following order as the application runs:

Event When
ApplicationStartingEvent Start of a run, before any processing except registration of listeners and initialisers
ApplicationEnvironmentPreparedEvent When Environment to use is known but before the context is created
ApplicationPreparedEvent After bean definitions are loaded but before refresh is started
ApplicationReadyEvent After refresh + related callbacks have been processed = App ready for service requests
ApplicationFailedEvent Startup exception has been raised

Be careful when using a hierarchy of SpringApplication instances, as a listener may receive multiple instances of the same type of application event. Implement ApplicationContextAware to inject context and compare it with the event’s context. If the listener is a @Bean, use @Autowired.

Reference: Application Events and Listeners.

Web environment

Call setWebEnvironment(false) when using SpringApplication within a JUnit test.

Reference: Web Environment.

Externalised configuration

Run the same application code no matter what the environment!

Pass your configuration with:

  • Properties files
  • YAML files
  • Environment variables
  • Command-line arguments

Property values can then be injected into beans using @Value accessed via:

Properties are considered in a specific order, go have a look at it.

Reference: Externalized configuration.

Relaxed binding

Interestingly, there is no need for an exact match between Environment and @ConfigurationProperties beans property names.

Example:

@ConfigurationProperties(prefix="person")
public class OwnerProperties {

	private String firstName;

	public String getFirstName() {
		return this.firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

}

To pass the firstName property you can use:

Property Format Usage
person.firstName Camel case Standard
person.first-name Kebab case Recommended in .properties and .yml files
person.first_name Underscore notation Alternative format in .properties and .yml files
PERSON_FIRSTNAME Upper case Environment variables

Reference: Relaxed binding.

Profiles

Segregate parts of your application to make them available only in certain environments.

Applies to @Component and @Configuration when marked with @Profile.

@Configuration
@Profile("production")
public class ProductionConfiguration {

	// ...

}

Then, specify which profiles are active using spring.profiles.active=dev,hsqldb or on the command line with --spring.profiles.active=dev,hsqldb.

Profiles also allow per-profile configuration files.

Reference: Profiles.

Developing web applications

  • Spring MVC which covers:
    • Auto-config
    • HttpMessageConverters
    • Custom JSON serializers and deserializers
    • MessageCodesResolver
    • Static content, including Favicon
    • ConfigurableWebBindingInitializer
    • Template engines
    • Error Handling, including custom error pages (Possibly outside of Spring MVC)
    • Spring HATEOAS
    • CORS
  • Spring WebFlux for async which covers:
    • Auto-config
    • HTTP Codecs with HttpMessageReaders and HttpMessageWriters
    • Static content
    • Template engines
    • Error Handling, including custom error pages
  • JAX-RS and Jersey
  • Embedded Servlet Container Support

Reference: Developing web applications.

More on Spring webflux

Security

Defaults to basic auth when enabled. OAuth2 also supported OOTB.

Refer to the Spring Security Reference.

Reference: Security

Data stores

Depending on your needs, refer to SQL databases and NoSQL databases (which includes SolR and ElasticSearch) documentations where you will find details about common data stores.

Caching

Refer to Spring documentation for details.

Example:

import org.springframework.cache.annotation.Cacheable
import org.springframework.stereotype.Component;

@Component
public class MathService {

	@Cacheable("piDecimals")
	public int computePiDecimal(int i) {
		// ...
	}

}

Here, before invoking computePiDecimal,

  1. abstraction looks for an entry in piDecimals cache that matches the i argument
  2. if an entry is found,
    • content retrieved from the cache is returned to the caller and computePiDecimal is not invoked
  3. else
    • Method is invoked and piDecimals cache is updated before returning the value to the caller.

Reference: Caching.

Cache providers

Many cache providers are supported, including Couchbase and Redis. See the list of supported cache providers.

Disabling caching

You may want to disable caching altogether in certain environments even if @EnableCaching is present in configuration.

A handy way of doing it would be to force the none cache type:

spring.cache.type=none

Messaging

Support for both JMS and AMPQ.

  • JMS (Java Message Service)
    • ActiveMQ
    • Artemis
  • AMQP (Advanced Message Queueing Protocol)
    • RabbitMQ
    • Apache Kafka

Reference: Messaging.

REST clients

RestTemplate

RestTemplate is a convenient way of handling your calls to other REST services.

Example:

@Service
public class MyService {

	private final RestTemplate restTemplate;

	public MyBean(RestTemplateBuilder restTemplateBuilder) {
		this.restTemplate = restTemplateBuilder.build();
	}

	public Details someRestCall(String name) {
		return this.restTemplate.getForObject("/{name}/details", Details.class, name);
	}

}

Reference: Calling REST Services with RestTemplate

WebClient

When in use with WebFlux. WebClient is fully reactive.

Example:

@Service
public class MyService {

	private final WebClient webClient;

	public MyBean(WebClient.Builder webClientBuilder) {
		this.webClient = webClientBuilder.baseUrl("http://example.org").build();
	}

	public Mono<Details> someRestCall(String name) {
		return this.webClient.get().url("/{name}/details", name)
						.retrieve().bodyToMono(Details.class);
	}

}

Reference: Calling REST Services with WebClient.

Testing

Reference: Testing

WebSockets

Accessible through the spring-boot-starter-websocket module. Documentation on spring framework websockets

MQTT is available through sprint integration

Reference: Websockets.

Further reading