Software architecture has evolved rapidly in the last few years. This shifting landscape has moved from monoliths deployed onto on-premises servers then to the cloud with AWS and Azure and next to “serverless” (which are still technically deployed servers). Application development frameworks like Spring Boot and Spring Cloud simplify and accelerate the process of creating robust cloud-ready software.
In the sections that follow, we will briefly discuss each type of software architecture and its advantages.
Mainframes, powerful computers with ample memory and processing power, are capable of performing a large number of transactions. Traditionally, COBOL and assembler are the languages of choice for programming applications on mainframes. Modern iterations of the mainframe now support programming in higher level languages like C++ and Java and can be developed using modern IDEs (integrated development environments) like Visual Studio Code.
The biggest draw of using a mainframe is the “RAS” value proposition: reliability, availability, and serviceability. Mainframes have self-checking and recovery built into the hardware, failures in components are isolated from the other parts of the system, and they allow for replacement of hardware and software components without the need for downtime.
In a monolith, the whole software application is developed and maintained within one unified codebase. These applications run on a single server or can have multiple copies of the same application running behind a load balancer.
Simplicity is the major advantage of this architecture; developers can easily follow the application flow since there are no external dependencies and the entire application logic is self-contained.
Through the use of service interfaces, service-oriented architecture (SOA) makes software components reusable. These interfaces are defined using the Web Services Description Language (WSDL), which consists of standard tags based in XML.
SOA serves as a stepping stone between monolithic architecture and microservices and is typically created by exposing existing functions from the legacy systems via WSDL interfaces.
A microservices architecture breaks an application down into a number of independently deployed services. These services are divided by business capability, each performing a sole responsibility. This flexibility allows different teams to own and iterate on separate parts of the application with minimal disturbance to the other services.
Microservices can be scaled individually according to demand, which optimizes resource utilization. Another major advantage of microservices is that they use the lightweight HTTP protocol for communication, whereas SOA relies on SOAP (Simple Object Access Protocol).
In recent years, “serverless” has become the new buzz word in the application development space. Serverless refers to the abstraction of infrastructure from the developer and emphasizes focusing on functions and services that solve a particular business problem. These functions are assumed to be short-lived—long-running functions can rack up significant costs when compared to traditional approaches where the infrastructure is managed by the developer.
Beyond serverless, there’s the choice to go no-code. Developers can simply use a UI to drag and drop elements and configure and integrate external services with a few mouse clicks.
Monolithic architecture is a popular approach to building web applications even today because it’s easy to implement and quick to get up and running. However, a few common issues arise when the application starts growing in size:
As we’ve seen, microservices architecture is an application that is divided into loosely coupled components or modules. This division is best done according to business capabilities. For example, the figure below shows the division of microservices for an e-commerce application.
Microservices work great when building a complex application that requires a larger team of developers. Because of the loosely coupled nature, each team can iterate quickly and independently of the other.
The Spring Framework is a widely adopted Java application development framework. Over the years, the framework has evolved and now encompasses multiple components like Spring Boot, Spring Data, and Spring Cloud, to name a few. When using Spring Boot to build microservices, developers can generate a project with most of the boilerplate configuration done in a matter of minutes. Similar to the Spring Cloud application framework, a lot of common patterns are implemented out of the box.
The Spring Framework is a robust, open-source platform for developing enterprise-grade Java applications. Its comprehensive programming and configuration model streamlines the creation of resilient software that’s easy to scale. Central to Spring are principles like dependency injection (DI) and aspect-oriented programming (AOP), which help developers build modular, testable, and maintainable code.
A core feature of Spring is its Inversion of Control (IoC) container, which handles the creation, configuration, and lifecycle management of application components.This allows for a modular approach to application design and facilitates better management of dependencies. Spring also offers powerful support for integrating with various data access technologies (like JDBC, JPA, and Hibernate), making it easier to interact with databases.
Spring’s modular design lets developers pick and use only the components they need: for example, Spring MVC for web development, Spring Security for authentication and authorization, and Spring Boot for fast, low-configuration application setup.
The significance of the Spring Framework lies in its ability to streamline Java development by reducing boilerplate code and promoting good design practices. It has become a de facto standard in the Java ecosystem, widely adopted in both small-scale and enterprise applications due to its flexibility, scalability, and rich feature set.
Spring Boot is an enhancement of the Spring Framework designed to streamline and speed up the creation of Spring applications. While the traditional Spring Framework offers extensive features for building robust applications, it often requires significant configuration and setup. Spring Boot addresses these challenges by offering convention over configuration, auto-configuration, and starter dependencies, which significantly reduce the amount of boilerplate code and manual setup required.
Simply put, Spring Boot builds on the foundations of the Spring Framework but introduces several enhancements to streamline development. With auto-configuration, Spring Boot can intelligently guess the necessary configurations based on the libraries present in the project, allowing developers to get started quickly without needing to define every detail. Starter dependencies group commonly used libraries into cohesive modules, making dependency management more straightforward and avoiding version conflicts.
Another key advantage is the built-in embedded server (like Tomcat or Jetty), which removes the need to deploy applications on an external server. This simplifies the process of building, testing, and running applications using simple commands like java -jar.
Spring Boot also includes robust support for microservices architecture, metrics, health checks, and externalized configuration, making it ideal for modern cloud-native development. Overall, Spring Boot represents a natural evolution of the Spring Framework, enabling rapid, efficient, and scalable Java application development with minimal effort.
Spring Cloud is a toolkit based on Spring Framework and Spring Boot designed to address common challenges developers encounter when creating microservices in highly distributed systems. It simplifies the development and deployment of cloud-native applications by offering a set of abstractions and tools tailored for distributed environments.
Here are the key features of Spring Cloud and how they address common problems in distributed systems:
By abstracting the complexity of building and managing microservices, the Spring Cloud application framework enables developers to focus on business logic rather than infrastructure concerns, making it a powerful framework for modern cloud-native applications.
In this article, we have detailed how software architecture has evolved over the years from mainframe applications to monoliths deployed on a single server to microservices and serverless applications deployed across multiple servers. Each of these architectural styles has its strengths and weaknesses, but we’ve seen how microservices architecture solves many of the issues related to scaling modern software applications. We have also briefly introduced the Spring Framework. In Part 2, we’ll get into more details and implement a reference architecture using the various libraries provided by the Spring Framework.