Spring is an open source modular framework for the JVM platform. A framework is a collection of libraries whose primary goal is to address common software development problems. The framework should solve these problems in a generic form.
Rod Johnson created the Spring Framework in 2002 together with his book publication, which was called Expert One-on-One J2EE Design and Development. The idea behind the creation of the framework was to tackle the complexities of Java Enterprise Edition.
At that time, this kind of solution-focused a lot on the details of the infrastructure, and a developer using the solution would spend a lot of time writing code to solve infrastructural problems. Since its creation, one of Rod Johnson's primary concerns has been to increase developer productivity.
The framework was first seen as a lightweight container for Java Runtime Environment, and it became popular in the community, especially because of the dependency injection feature. The framework made dependency injection incredibly easy. Developers hadn't seen such a feature before, and as a consequence, people the world over adopted the project. Year by year, its popularity within the software development world has been increasing.
In the earliest versions, the framework had to work with the XML file to configure the container. At the time, this was so much better than J2EE applications, where it was necessary to create many
Ant files to create the boilerplate classes and interfaces.
The framework was always seen as an advanced technology for the Java platform, but in 2014, the Spring team launched the Spring Boot platform. This platform was incredibly successful in the Java Enterprise ecosystem, and it changed the way in which developers built Java Enterprise applications.
Today, Spring is the de facto framework for Java development, and companies around the world use it in their systems. The community is vibrant and contributes to development in different ways, such as opening issues, adding the code, and discussing the framework in the most important Java conferences around the world. Let's look at and play with the famous framework for Java developers.
We will cover the following topics in this chapter:
- Main modules of the Spring Framework
- Spring annotations for each module
- Setting up the development environment
- Docker and Docker commands
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.
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).
- 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.
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 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.
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 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.
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,
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.
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
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.
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
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.
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.
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.
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.
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.
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
@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.
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
PagingAndSortingRepository, and their names are self-explanatory.
CrudRepository implements the CRUD behaviors, such as
PagingAndSortingRepository 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.
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 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:
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:
- HTTP Basic
http .formLogin() .loginPage("/login") .failureUrl("/login?error") .and() .authorizeRequests() .antMatchers("/signup","/about").permitAll() .antMatchers("/admin/**").hasRole("ADMIN") .anyRequest().authenticated();
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.
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 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.
- 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.
- 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.
- 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
@HystrixCommandand 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
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.
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:
In Chapter 7, Airline 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.
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).
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.
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
The projects support three message brokers as the transport layer:
- Apache Kafka
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
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.
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:
- Web services
- And much more
There are three main concepts of Enterprise application integration:
- 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.
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.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.
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.
- 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
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.
- Build tool
We will install JDK version 8.0. This version is fully supported in Spring Framework 5. We will present the steps to install Maven 3.3.9, the most famous build tool for Java development, and in the last part, we will show you some detailed instructions on how to install IntelliJ IDEA Community Edition. We will use Ubuntu 16.04, but you can use your favorite OS. The installation steps are easy.
Also, it is possible to use an Oracle JDK, but you should pay attention to the
License and Agreements.
To install OpenJDK, we will open a terminal and run the following command:
sudo apt-get install openjdk-8-jdk -y
We can find more information on how to install Java 8 JDK in the installation section (http://openjdk.java.net/install/) of the OpenJDK page.
Check the installation using the following command:
You should see the OpenJDK version and its relevant details displayed as follows:
Now that we have installed the Java development kit, we are ready for the next step. In the real world, we must have a build tool to help developers to compile, package, and test the Java applications.
Let's install Maven in the next section.
Maven is a popular build tool for Java development. Some important open source projects were built using this tool. There are features that facilitate the build process, standardize the project structure, and provide some guidelines for best practices development.
We will install Maven, but the installation step should be executed after the OpenJDK installation.
Open a terminal and execute the following:
sudo apt-get install maven -y
Check the installation using this command:
You should see the following output, although the version may be different for you:
Well done. Now we have Maven installed. Maven has a vibrant community that produces many plugins to help developers with important tasks. There are plugins to execute a unit test and plugins to prepare the project for the release event that can be integrated with SCM software.
We will use the
spring boot maven plugin and
docker maven plugin. The first converts our application to a JAR file and the second enables us to integrate with Docker Engine to create images, run containers, and much more. In the next few chapters, we will learn how to configure and interact with these plugins.
The IDE is an important tool to help developers. In this book, we will use the IntelliJ IDEA as an official tool for developing our projects. There are no restrictions for other IDEs because the project will be developed using Maven as a build tool.
The IDE is a personal choice for developers, and in general, it involves passion; what some people love, other developers hate. Please feel free to use your favorite.
IntelliJ IDEA is a JetBrains product. We will use the Community Edition, which is open source and a fantastic tool with which to code Java and Kotlin. The tool offers a fantastic autocomplete feature, and also fully supports Java 8 features.
Go to https://www.jetbrains.com/idea/download/#section=linux and download the Community Edition. We can extract the
tar.gz and execute it.
The Spring Tools Suite is based on Eclipse IDE, provided by the Eclipse Foundation, of course. The goal is to provide support for the Spring ecosystem and make the developer's life easier. Interesting features such as Beans Explorer are supported in this tool.
Download the tool at the following link:http://download.springsource.com/release/STS/3.6.4.RELEASE/dist/e4.4/groovy-grails-tool-suite-3.6.4.RELEASE-e4.4.2-linux-gtk-x86_64.tar.gz
During the development phase, Docker enables developers to spin up different infrastructure services such as databases and service discoveries like Consul without installation in the current system operational. It helps the developers because developers do not need to install these kinds of systems in the operating system layer. Usually, this task can cause conflicts with the libraries during the installation process and consumes a lot of time.
Sometimes, developers need to install the exact version. In this case, it is necessary to reinstall the whole application on the expected version. It is not a good thing because the developer machine during this time becomes slow. The reason is quite simple, there are many applications that are used during software development.
Docker helps developers at this stage. It is quite simple to run a container with MongoDB. There is no installation and it enables developers to start the database with one line. Docker supports the image tag. This feature helps to work with different versions of the software; this is awesome for developers who need to change the software version every time.
Another advantage is that when the developers need to deliver the artifacts for test or production purposes, Docker enables these tasks via Docker images.
Docker helps people to adopt the DevOps culture and delivers amazing features to improve the performance of the whole process.
Let's install Docker.
The easiest way to install Docker is to download the script found at https://get.docker.com:
curl -fsSL get.docker.com -o get-docker.sh
After the download is completed, we will execute the script as follows:
Wait for the script execution and then check the Docker installation using the following command:
The output needs to look like the following:
Sometimes, the version of Docker can be increased, and the version should be at least 17.10.0-ce.
Finally, we will add the current user to the Docker group, and this enables us to use the Docker command line without the
sudo keyword. Type the following command:
sudo usermod -aG docker $USER
We need to log out to effect these changes. Confirm whether the command works as expected by typing the following. Make sure that the
sudo keyword is not present:
The output should be as follows:
Now, we will introduce some Docker concepts. This book is not about Docker, but some basic instructions on how to use Docker are necessary to interact with our containers during the next few chapters. Docker is a de facto tool that is used to manage containers.
The Docker image is like a template for a Docker container. It contains a set of folders and files that are necessary to start the Docker container. We will never have an image in execution mode. The image provides a template for Docker Engine to start up the container. We can create an analogy with object orientation to understand the process better. The image is like a class that provides an infrastructure to instantiate some objects, and instances are like a container.
Also, we have a Docker registry to store our images. These registries can be public or private. Some cloud vendors provide these private registries. The most famous is Docker Hub. It can be free, but if you choose this option, the image should be public. Of course, Docker Hub supports private images, but in this case, you have to pay for the service.
Docker containers are a lightweight virtualization. The term lightweight means that Docker uses the SO functionalities to cage the system process and manager memory, processors, and folders. This is different from virtualization with VMs because, in this mode, the technology needs to simulate the whole SO, drivers, and storage. This task consumes a lot of computational power and can sometimes be inefficient.
A Docker network is a layer that provides runtime isolation for containers. It is a kind of sandbox in which to run containers that are isolated from other containers. When the Docker is installed, by default it creates three networks that should not be removed. These three networks are as follows:
Bridge can be used for the local environment, and it means this kind of network is allowed on a single host. It will be useful for our applications because it promotes isolation between containers regarding security. This is a good practice. The name of the container attached to this kind of network can be used as a DNS for the container. Internally, Docker will associate the container name with the container IP.
The overlay network provides the ability to connect containers to different machines. This kind of network is used by Docker Swarm to manage the container in a clustered environment. In the newest version, the Docker Compose tool natively supports Docker Swarm.
Docker volumes are the suggested way to persist data outside of a container. These volumes are fully managed by Docker Engine, and these volumes can be writable and readable depending on the configuration when they are used with a Docker command line. The data of these volumes is persisted on a directory path on a host machine.
There is a command-line tool to interact with volumes. The base of this tool is the
docker volume command; the
--help argument on the end shows the help instructions.
docker run [OPTIONS] IMAGE[:TAG|@DIGEST] [COMMAND] [ARG...]
The options arguments enable some configurations for the container, for instance, the
--name argument permits you to configure a name for a container. It is important for DNS when the container is running in a bridge network.
The network settings can be configured on the
run command as well, and the parameter is
-- net. This enables us to configure the network to which the container will be attached.
Another important option is
detached. It indicates whether the container will run in the background. The
-d parameter instructs Docker to run a container in the background.
docker container attach
docker container commit
docker container cp
docker container create
docker container diff
docker container exec
docker container export
docker container inspect
docker container kill
docker container logs
docker container ls
docker container pause
docker container port
docker container prune
docker container rename
docker container restart
docker container rm
docker container run
docker container start
docker container stats
docker container stop
docker container top
docker container unpause
docker container update
docker container wait
There are some important commands here. The
docker container exec permits you to run commands on a running container. This is an important task to debug or look inside the container files. The
docker container prune removes the stopped containers. It is helpful in the development cycle. There are some known commands, such as
docker container rm,
docker container start,
docker container stop, and
docker container restart. These commands are self-explanatory and have similar behaviors.
docker network create
docker network connect
docker network ls
docker network rm
docker network disconnect
docker network inspect
docker network create,
docker network ls, and
docker network rm are the main commands. It is possible to compare them with the Linux commands, where the
rm command is used to remove things and the
ls command is usually used to list things such as folders. The
create command should be used to create networks.
docker network connect and
docker network disconnect commands allow you to connect the running container to the desired network. They may be useful in some scenarios.
docker network inspect command provides detailed information on the requested network.
docker volume create
docker volume inspect
docker volume ls
docker volume prune
docker volume rm
docker volume create,
docker volume rm and
docker volume ls commands are effectively used to manage the
docker volume by Docker Engine. The behaviors are quite similar to those of the networks, but for volumes. The
create command will create a new volume with some options allowed. The
ls command lists all volumes and the
rm command will remove the requested volume.
In this chapter, we looked at the main concepts of Spring Framework. We understood the main modules of the framework and how these modules can help developers to build applications in different kinds of architecture, such as messaging applications, REST APIs, and web portals.
We also spent some time preparing our development environment by installing essential tools, such as Java JDK, Maven, and IDE. This was a critical step to take before we continue to the next chapters.
We used Docker to help us to set up a development environment, such as containers for databases and delivery for our application in Docker images. We installed Docker and looked at the main commands for managing containers, networks, and volumes.
In the next chapter, we will create our first Spring application and put it into practice!