Book Image

Spring 5.0 By Example

By : Claudio Eduardo de Oliveira
Book Image

Spring 5.0 By Example

By: Claudio Eduardo de Oliveira

Overview of this book

With growing demands, organizations are looking for systems that are robust and scalable. Therefore, the Spring Framework has become the most popular framework for Java development. It not only simplifies software development but also improves developer productivity. This book covers effective ways to develop robust applications in Java using Spring. The book has three parts, where each one covers the building of a comprehensive project in Java and Spring. In the first part, you will construct a CMS Portal using Spring's support for building REST APIs. You will also learn to integrate these APIs with AngularJS and later develop this application in a reactive fashion using Project Reactor, Spring WebFlux, and Spring Data. In the second part, you’ll understand how to build a messaging application, which will consume the Twitter API and perform filtering and transformations. Here, you will also learn about server-sent events and explore Spring’s support for Kotlin, which makes application development quick and efficient. In the last part, you will build a real microservice application using the most important techniques and patterns such as service discovery, circuit breakers, security, data streams, monitoring, and a lot more from this architectural style. By the end of the book, you will be confident about using Spring to build your applications.
Table of Contents (17 chapters)
Title Page
Copyright and Credits
Dedication
Packt Upsell
Contributors
Preface
Index

Spring modularity


Since its foundation, the framework has had a particular focus on modularity. It is an important framework characteristic because it makes the framework an excellent option for different architectural styles and different parts of applications.

It means the framework is not an opinionated, full-stack framework that dictates the rules to make everything work. We can use the framework as we need and integrate it with a wide range of specification and third-party libraries.

For example, for portal web applications, the Spring MVC supports features such as template engines and REST endpoints and integrates them with the popular JavaScript framework, AngularJS.

Also, if the application needs support for a distributed system, the framework can supply an amazing module called Spring Cloud, which has some essential features for distributed environments, such as service registration and discovery, a circuit breaker, intelligent routing, and client-side load balancing.

Spring makes the development applications for Java Runtime easy with different languages, such as Java, Kotlin, and Groovy (with which you can choose the flavor and make the development task fun).

It is divided into various modules. The main modules are as follows:

  • Spring Core
  • Spring Data
  • Spring Security
  • Spring Cloud
  • Spring Web-MVC

In this book, we will cover the most common solutions involved in Java Enterprise applications, including the awesome Spring Cloud project. Also, we can find some interesting projects such as Spring Batch and Spring Integration, but these projects are for specific needs.

Spring Core Framework

This module is the base of the framework and contains the essential support for dependency injection, web features supported by Spring MVC (model-view-controller) and the pretty new WebFlux frameworks, and aspect-oriented programming. Also, this module supports the foundation for JDBC, JMS, JPA and a declarative way to manage transactions. We will explore it and understand the main projects of this module. So let's do it!

Core container

The core container is the basis of the whole Spring ecosystem and comprehends four components—core, beans, context, and expression language.

Core and beans are responsible for providing the fundamentals of the framework and dependency injection. These modules are responsible for managing the IoC container, and the principal functions are the instantiation, configuration, and destruction of the object residents in the Spring container.

Note

Spring contexts are also called Spring IoC containers, which are responsible for instantiating, configuring, and assembling beans by reading configuration metadata from XML, Java annotations, and/or Java code in the configuration files.

There are two critical interfaces inside these modules—BeanFactory and ApplicationContext. The BeanFactory takes care of the bean lifecycle, instantiating, configuring, managing, and destroying, and the ApplicationContext helps developers to work with files resources in a generic way, enable to publish events to registered listeners. Also, the ApplicationContext supports internationalization and has the ability to work with messages in different Locales.  

These modules help the context component to provide a way to access the objects inside the container. The context component has the ApplicationContext interface with the essential class for the container.

Note

Some common annotations are @Service, @Component, @Bean, and @Configuration.

Spring Messaging

Spring Framework supports a wide range of messaging systems. The Java platform is recognized as providing excellent support for messaging applications, and Spring Framework follows this approach and offers a variety of projects to help developers to write powerful applications with more productivity and fewer lines of infrastructure code. The basic idea of these projects is to provide some template classes that have the convenience methods to interact with the messaging systems.

Also, the project supplies some listener annotations to provide support for listening to messages from the brokers. The framework maintains the standard for different projects. In general, the prefix of the annotations is the name of the messaging system, for example, @KafkaListener.

The framework supplies many abstractions to create messaging applications in a generic way. This is interesting stuff because the application requirements change during the application lifecycle and the message broker solution may change as well. Then, with small changes, the application built with the Spring message module can work in different brokers. This is the goal.

Spring AMQP

This subproject supports the AMQP protocol in Spring Framework. It provides a template to interact with the message broker. A template is like a super high-level API that supports the send and receive operations. 

There are two projects in this set: spring-amqp, which can be used for ActiveMQ for instance, and spring-rabbit, which adds support for the RabbitMQ broker. This project enables broker administration through the APIs to declare queues, bindings, and exchanges.

These projects encourage the extensive use of dependency injection provided by the core container, because they make the configuration more declarative and easy to understand.

Nowadays, the RabbitMQ broker is the popular choice for the messaging applications, and Spring provides full support for client interactions up to the level of administration tasks.

Note

Some common annotations are @Exchange and @QeueueBinding.

Spring for Apache Kafka

Spring for Apache Kafka supports the broker-based Apache Kafka applications. It provides a high-level API to interact with Apache Kafka. Internally, the projects use the Kafka Java APIs.

This module supports the annotation programming model. The basic idea is that with a couple of annotations and some POJO models, we can bootstrap the application and start listening to and producing messages.

KafkaTemplate is a central class of this project. It enables us to send messages to Apache Kafka with a high-level API. Asynchronous programming is supported as well.

This module offers support for transactions via annotations. This feature is enabled via standard transactional annotations used in Spring-based applications, such as @Transactional.

We also learned about Spring AMQP. This project adds the Spring concept of creating applications based on this broker. The dependency injection features are supported as well.

Note

Some common annotations are @EnableKafka and @KafkaListener.

Spring JMS

The idea of this project provides a JMS integration with ideas of Spring Framework projects and supplies a high-level API to interact with brokers. The worst part of a JMS specification is that it has a lot of boilerplate code to manage and close connections.

The JmsTemplate is a central class for this module, and it enables us to send messages to the broker. The JMS specification has a lot of intrinsic behaviors to handle the creation and releases resources, for instance, the JmsTemplate class do this tasks automatically for developers.

The module also supports transactional requirements. The JmsTransactionManager is the class that handles the transactional behavior of the Spring JMS module.

Spring removes the boilerplate code with a couple of annotations. The framework increases the readability of the code and makes the code more intuitive as well.

Note

Some common annotations are @JmsListener and @EnableJms.

Spring Web MVC

This module is the first one built by the Spring Team to support the web applications in Spring Framework. This module uses the Servlet API as its foundation, and then these web applications must follow the Servlet Specification and be deployed into servlet containers. In version 5.0, the Spring Team created a Reactive web framework, which will be covered later in this book.

The Spring Web MVC module was developed using the front controller pattern. When the framework was created, this pattern was a common choice for many frameworks, such as Struts and JSF, among others. Under the hood, there is the main servlet in Spring called DispatcherServlet. This servlet will redirect through an algorithm to do the desired work.

It enables developers to create amazing web applications on the Java platform. This portion of the framework provides full support to develop this kind of application. There are some interesting features for this purpose, such as support for internationalization and support for handling cookies. Also, multipart requests are an exciting feature for when the application needs to handle upload files and support routing requests. 

These characteristics are common for most web applications, and the framework has excellent support for these features. This support makes the framework a good choice for this kind of application. In Chapter 2, Starting in the Spring World - The CMS Application, we will create an application using this module and the main features will be explored in depth.

The module has full support for annotation programming since to declare HTTP endpoints until to wrap the request attribute in an HTTP request. It makes the application extremely readable without the boilerplate code to get the request parameter, for example.

Web application-wise, it enables developers to work with robust template engines such as Thymeleaf and Freemarker. It is entirely integrated with routing features and bean validation.

Also, the framework allows developers to build REST APIs with this module. Given all of this support, the module has become a favorite in the Spring ecosystem. Developers have started to create APIs with this stack, and some important companies have started to use it, especially given that the framework provides an easy way to navigate through the annotations. Because of this, the Spring Team added the new annotation @RestController in version 4.0.

We will work a lot with this module. Chapter by chapter, we will learn interesting things about this part of the framework.

Note

Some common annotations are @RequestMapping, @Controller, @Model@RestController, and @RequestBody.

Spring WebFlux

A new module introduced in Spring 5.0, Spring WebFlux, can be used to implement web applications built with Reactive Streams. These systems have nonblocking characteristics and are deployed in servers built on top of Netty, such as Undertown and servlet containers that support + 3.1.

Note

Netty is an open source framework that helps developers to create network applications—that is, servers and clients using the asynchronous, event-driven pattern. Netty provides some interesting advantages, such as lower latency, high throughput, and less resource consumption. You can find more information at https://netty.io.

This module supports annotations based on Spring MVC modules, such as @GetMapping, @PostMapping, and others. This is an important feature that enables us to migrate to this new version. Of course, some adjustments are necessary, such as adding Reactor classes (Mono or Flux).

This module meets the modern web requirements to handle a lot of concurrent channels where the thread-per-request model is not an option.

We will learn about this module in Chapter 3, Adding Persistence with Spring Data and Putting it into Reactive Fashion and implement a fully Reactive application based on Reactive Streams.

Note

Some common annotations are @RequestMapping, @RestController, and  @RequestBody.

Spring Data

Spring Data is an interesting module that provides the easiest way to manage application data with Spring-based programming. The project is an umbrella project, with subprojects to support different databases technologies, even relational and nonrelational databases. The Spring Team supports some databases technologies, such as Apache Cassandra, Apache Solr, Redis, and JPA Specification, and the community maintains the other exciting projects, such as ElasticSearch, Aerospike, DynamoDb, and Couchbase. The full list of projects can be found at http://projects.spring.io/spring-data.

The goal is to remove the boilerplate code from the persistence code. In general, the data access layer is quite similar, even in different projects, differing only in the project model, and Spring Data provides a powerful way to map the domain model and repository abstraction.

There are some central interfaces; they're a kind of marker to instruct the framework to choose the correct implementation. Under the hood, Spring will create a proxy and delegate the correct implementation. The amazing thing here is that developers don't have to write any persistence code and then take care of this code; they simply choose the required technology and Spring takes care of the rest.

The central interfaces are CrudRepository and PagingAndSortingRepository, and their names are self-explanatory. CrudRepository implements the CRUD behaviors, such as create, retrieval, update, and deletePagingAndSortingRepository is an extension of CrudRepository and adds some features such as paging and sorting. Usually, we will find derivations of these interfaces such as MongoRepository, which interacts with MongoDB database technology.

Note

Some common annotations are @Query, @Id, and @EnableJpaRepositories.

Spring Security

Security for Java applications was always a pain for developers, especially in Java Enterprise Edition. There was a lot of boilerplate code to look up objects in the application servers, and the security layer was often heavily customized for the application.

In that chaotic scenario, the Spring Team decided to create a Spring Security project to help developers handle the security layer on the Java application.

In the beginning, the project had extensive support for Java Enterprise Edition and integration with EJB 3 security annotations. Nowadays, the project supports many different ways to handle authorization and authentication for Java applications.

Spring Security provides a comprehensive model to add authorization and authentication for Java applications. The framework can be configured with a couple of annotations, which makes the task of adding a security layer extremely easy. The other important characteristics concern how the framework can be extended. There are some interfaces that enable developers to customize the default framework behaviors, and it makes the framework customized for different application requirements.

It is an umbrella project, and it is subdivided into these modules:

  • spring-security-core
  • spring-security-remoting
  • spring-security-web
  • spring-security-config
  • spring-security-ldap
  • spring-security-acl
  • spring-security-cas
  • spring-security-openid
  • spring-security-test

These are the main modules, and there are many other projects to support a wide range of types of authentication. The module covers the following authentication and authorization types:

  • LDAP
  • HTTP Basic
  • OAuth
  • OAuth2
  • OpenID
  • CAAS
  • JAAS

The module also offers a domain-specific language (DSL) to provide an easy configuration. Let's see a simple example:

http
  .formLogin()
    .loginPage("/login")
     .failureUrl("/login?error")
      .and()
    .authorizeRequests()
      .antMatchers("/signup","/about").permitAll()
      .antMatchers("/admin/**").hasRole("ADMIN")
      .anyRequest().authenticated();

Note

The example was extracted from the spring.io blog. For more details, go to https://spring.io/blog/2013/07/11/spring-security-java-config-preview-readability/.

As we can see, the DSL makes the configuration task extremely easy and very understandable.

Spring Security's main features are as follows:

  • Session management
  • Protection against attacks (CSRF, session fixation, and others)
  • Servlet API integration
  • Authentication and authorization

We will learn more about Spring Security in Chapter 8, Circuit Breakers and Security. We will also put it into practice.

Note

@EnableWebSecurity is a common annotation.

Spring Cloud

Spring Cloud is another umbrella project. The primary goal of this project is to help developers create distributed systems. Distributed systems have some common problems to solve and, of course, a set of patterns to help us, such as service discovery, circuit breakers, configuration management, intelligent route systems, and distributed sessions. Spring Cloud tools have all these implementations and well-documented projects.

The main projects are as follows:

  • Spring Cloud Netflix
  • Spring Cloud Config
  • Spring Cloud Consul
  • Spring Cloud Security
  • Spring Cloud Bus
  • Spring Cloud Stream

Spring Cloud Netflix

Spring Cloud Netflix is perhaps the most popular Spring module nowadays. This fantastic project allows us to integrate the Spring ecosystem with the Netflix OSS via Spring Boot AutoConfiguration features. The supported Netflix OSS libraries are Eureka for service discovery, Ribbon to enable client-side load balancing, circuit breaker via Hystrix to protect our application from external outages and make the system resilient, the Zuul component provides an intelligent routing and can act as an edge service. Finally, the Feign component can help developers to create HTTP clients for REST APIs with a couple of annotations.

Let's look at each of these:

  • Spring Cloud Netflix Eureka: The focus of this project is to provide service discovery for applications while conforming to Netflix standards. Service discovery is an important feature and enables us to remove hardcoded configurations to supply a hostname and ports; it is more important in cloud environments because the machine is ephemeral, and thus it is hard to maintain names and IPs. The functionality is quite simple, the Eureka server provides a service registry, and Eureka clients will contact its registers themselves.

Note

Some common annotations are @EnableEurekaServer and @EnableEurekaClient.

  • Spring Cloud Feign: The Netflix team created the Feign project. It's a great project that makes the configuration of HTTP clients for REST applications significantly easier than before. These implementations are based on annotations. The project supplies a couple of annotations for HTTP paths, HTTP headers, and much more, and of course, Spring Cloud Feign integrates it with the Spring Cloud ecosystem through the annotations and autoconfiguration. Also, Spring Cloud Feign can be combined with the Eureka server.

Note

Some common annotations are @EnableFeignClients and @FeignClient.

  • Spring Cloud Ribbon: Ribbon is a client-side load balancer. The configuration should mainly provide a list of servers for the specific client. It must be named. In Ribbon terms, it is called the named client. The project also provides a range of load-balancing rules, such as Round Robin and Availability Filtering, among others. Of course, the framework allows developers to create custom rules. Ribbon has an API that works, integrated with the Eureka server, to enable service discovery, which is included in the framework. Also, essential features such as fault tolerance are supported because the API can recognize the running servers at runtime.

Note

Some common annotations are @RibbonClient and @LoadBalanced.

  • Spring Cloud Hystrix: An acclaimed Netflix project, this project provides a circuit breaker pattern implementation. The concept is similar to an electrical circuit breaker. The framework will watch the method marked with @HystrixCommand and watch for failing calls. If the failed calls number more than a figure permitted in configuration, the circuit breaker will open. While the circuit is open, the fallback method will be called until the circuit is closed and operates normally. It will provide resilience and fault-tolerant characteristics for our systems. The Spring ecosystem is fully integrated with Hystrix, but it works only on the @Component and @Service beans.

Note

Some common annotations are @EnableCircuitBreaker and @HystrixCommand.

Spring Cloud Config

This exciting project provides an easy way to manage system configurations for distributed systems, and this is a critical issue in cloud environments because the file system is ephemeral. It also helps us to maintain different stages of the deployment pipeline. Spring profiles are fully integrated with this module.

We will need an application that will provide the configuration for other applications. We can understand its workings by thinking of the concepts of the server and the client, the server will provide some configurations through HTTP and the client will look up the configuration on the server. Also, it is possible to encrypt and decrypt property values.

There are some storage implementations to provide these property files, and the default implementation is Git. It enables us to store our property files in Git, or we can use the file system as well. The important thing here is that the source does not matter.

Note

Git is a distributed version control. The tool is commonly used for development purposes, especially in the open-source community. The main advantage, when you compare it to some market players, such as SVN, is the distributed architecture.

There is an interesting integration between Spring Cloud Bus and this module. If they are integrated, it is possible to broadcast the configuration changes on the cluster. This is an important feature if the application configuration changes with frequency. There are two annotations that tell Spring to apply changes at runtime: @RefreshScope and @ConfigurationProperties.

In Chapter 7Airline Ticket System, we will implement an exciting service to provide external configurations for our microservices using this module. Server concepts will be explained in more detail. The client details will be presented as well.

Note

  @EnableConfigServer is a common annotation.

Spring Cloud Consul

Spring Cloud Consul provides integrations with Hashicorp's Consul. This tool addresses problems in the same way as service discovery, a distributed configuration, and control bus. This module allows us to configure Spring applications and Consul with a few annotations in a Spring-based programming model. Autoconfiguration is supported as well. The amazing thing here is that this module can be integrated with some Netflix OSS libraries, such as Zuul and Ribbon, via Spring Cloud Zuul and Spring Cloud Ribbon respectively (for example).

Note

@EnableDiscoveryClient is a common annotation. 

Spring Cloud Security

This module is like an extension from Spring Security. However, distributed systems have different requirements for security. Normally, they have central identity management, or the authentication lies with the clients in the case of REST APIs. Normally, in distributed systems, we have microservices, and these services might have more than one instance in the runtime environment whose characteristics make the authentication module slightly different from monolithic applications. The module can be used together with Spring Boot applications and makes the OAuth2 implementation very easy with a couple of annotations and a few configurations. Also, some common patterns are supported, such as single sign-on, token relay, and token exchange.

For the microservice applications based on the Spring Cloud Netflix, it is particularly interesting because it enables downstream authentication to work with a Zuul proxy and offers support from Feign clients. An interceptor is used to fetch tokens.

Note

Some commons annotations are @EnableOAuth2Sso and @EnableResourceServer.

Spring Cloud Bus

The main goal of this project is to provide an easy way to broadcast changes spread throughout the cluster. The applications can connect the distributed system nodes through the message broker.

It provides an easy way for developers to create a publish and subscribe mechanism using the ApplicationContext provided by Spring Container. It enables the possibility to create applications using the event-driven architecture style with the Spring Ecosystem.

To create custom events, we need to create a child class from RemoteApplicationEvent and mark the class to be scanned via @RemoteApplicationEventScan.

The projects support three message brokers as the transport layer:

  • AMQP
  • Apache Kafka
  • Redis

Note

@RemoteApplicationEventScan is a common annotation. 

Spring Cloud Stream

The idea behind this module is to provide an easy way to build message-driven microservices. The module has an opinionated way of configuration. It means we need to follow some rules to create these configurations. In general, the application is configured by the yaml|properties file.

The module supports annotations as well. This means that a couple of annotations are enough to create consumers, producers, and bindings; it decouples the application and makes it easy to understand. It supplies some abstractions around the message brokers and channels, and it makes the developer's life more comfortable and productive as well.

Spring Cloud Stream has Binder implementations for RabbitMQ and Kafka.

Note

Some common annotations are @EnableBinding, @Input, and @Output.

Spring Integration

This module supports a lot of Enterprise Application patterns and brings the Spring programming model to this topic. The Spring programming model enables extensive dependence injection support and is annotations programming-centric. The annotations instruct us as to how the framework needs to be configured and defines framework behaviors.

The POJO model is suggested because it is simple and widely known in the Java development world.

This project has some intersections with the other modules. Some other projects use these module concepts to do their work. There is a project called Spring Cloud Stream, for instance.

The Enterprise Integration patterns are based on a wide range of communication channels, protocols, and patterns. This project supports some of these.

The modules support a variety of features and channels, such as the following:

  • Aggregators
  • Filters
  • Transformers
  • JMS
  • RabbitMQ
  • TCP/UDP
  • Web services
  • Twitter
  • Email
  • And much more

There are three main concepts of Enterprise application integration:

  • Messages
  • Message channel
  • Message endpoint

Finally, the Spring Integration module offers a comprehensive way to create application integration and enables developers to do it using amazing support.

Note

Some common annotations are @EnableIntegration, @IntegrationComponentScan , and @EnablePublisher.

Spring Boot

Spring Boot was released in 2014. The idea behind this project was to present a way to deploy the web application outside of any container, such as Apache Tomcat, Jetty, and so on. The benefit of this kind of deployment is the independence from any external service. It allows us to run the web applications with one JAR file. Nowadays, this is an excellent approach because this forms the most natural way to adopt DevOps culture.

Spring Boot provides embedded servlet containers, such as Apache Tomcat, Jetty, and Undertow. It makes the development process more productive and comfortable when testing our web applications. Also, customizations during configuration are allowed via a configuration file, or by providing some beans.

There are some advantages when adopting the Spring Boot framework. The framework does not require any XML for configuration. This is a fantastic thing because we will find all the dependencies in the Java files. This helps the IDEs to assist developers, and it improves the traceability of the code. Another important advantage is that the project tries to keep the configuration as automatic as possible. Some annotations make the magic happen. The interesting thing here is that Spring will inject the implementation of any code that is generated at runtime.

The Spring Boot framework also provides interesting features to help developers and operations, such as health checks, metrics, security, and configuration. This is indispensable for modern applications where the modules are decomposed in a microservices architecture.

There are some other interesting features that can help the developers DevOps-wise. We can use the application-{profile}.properties or application.yaml files to configure different runtime profiles, such as development, testing, and production. It is a really useful Spring Boot feature.

Also, the project has full support for the tests, since the web layer up to the repository layer.

The framework provides a high-level API to work with unit and integration tests. Also, the framework supplies many annotations and helpers classes for developers.

The Spring Boot project is a production-ready framework with default optimized configurations for the web servers, metrics, and monitoring features to help the development team deliver high-quality software.

We can develop applications by coding in the Groovy and Java languages. Both are JVM languages. In version 5.0, the Spring Team announced the full support for Kotlin, the new language for JVM. It enables us to develop consistent and readable codes. We will look at this feature in depth in Chapter 7, Airline Ticket System.

Microservices and Spring Boot

The microservices architectural style, in general, is distributed, must be loosely coupled, and be well-defined. These characteristics must be followed when you want a microservices architecture.

Much of Spring Boot is aimed at developer productivity by making common concepts, such as RESTful HTTP and embedded web application runtimes, easy to wire up and use. In many respects, it also aims to serve as a micro-framework, by enabling developers to pick and choose the parts of the framework they need, without being overwhelmed by bulky or otherwise unnecessary runtime dependencies. This also enables Boot applications to be packaged into small units of deployment, and the framework is able to use build systems to generate those deployables as runnable Java archives.

The main characteristics of microservices are:

  • Small-grained components
  • Domain responsibility (orders, shopping carts)
  • Programming-language agnostic
  • Database agnostic

Spring Boot enables us to run an application on embedded web servers such as Tomcat, Jetty, and Undertow. This makes it extremely easy to deploy our components because it is possible to expose our HTTP APIs in one JAR.

The Spring Team even thinks in terms of developer productivity, and they offer a couple of projects called starters. These projects are groups of dependencies with some compatibilities. These awesome projects additionally work with the convention over configuration. Basically, they are common configurations that developers need to make on every single project. We can change these settings in our application.properties or application.yaml files.

Another critical point for microservices architecture is monitoring. Let's say that we're working on an e-commerce solution. We have two components, shopping cart and payments. The shopping cart probably needs to have several instances and payments need to have fewer instances. How can we check these several instances? How can we check the health of these services? We need to fire an alarm when these instances go down. This is a common implementation for all services. The Spring Framework supplies a module called Spring Boot Actuator that provides some built-in health checks for our application, databases, and much more.