VM.PL

Spring Framework in 2024: Your Key to Building More Efficient Systems

/ 29.01.2024
Java

TL;DR  

Efficiency is a key aspect of software development, and it can be understood in several contexts, including algorithmic efficiency, resource utilization, and developer productivity.  

ISO/IEC 25010 defines performance efficiency as a product's capability to perform its functions within specified time and throughput parameters and efficiently use resources under specified conditions. 

Spring Framework provides several features that contribute to efficiency in different contexts:  

  • Java 21 and virtual threads: Spring Boot 3.2 supports Java 21’ virtual threads, which are lighter-weight and more efficient than traditional threads.   
  • GraalVM: Support building native images, which can significantly reduce the startup time and memory footprint of Java applications.  
  • Event-driven: In Spring framework projects you can provide a comprehensive selection of event-driven solutions, including messaging brokers, and streaming processing.  
  • Enterprise integration design patterns: Spring Integration simplifies messaging within Spring applications and facilitates integration with external systems via declarative adapters.  
  • High-level messaging brokers: Spring provides extensive tools for seamless integration with messaging systems, such as JMS, AMQP, RabbitMQ, Kafka, and Pulsar.  
  • Streaming processing: Spring framework tools like Spring Cloud Stream simplify the creation of message-driven microservices, and Spring Cloud Data Flow simplifies building and deploying complex data processing pipelines for streaming and batch processing in Cloud Foundry and Kubernetes environments.  

Java and Spring Framework are popular tools for developing backend applications, and they are still going strong in 2024. This is due to its rich documentation, years of production experience, and plethora of open-source tools. 

What does efficiency mean in software development?  

Before we dig deeper into understanding what makes Spring Framework (still) a valid choice in modern backend development, we should start with some basic and theoretical knowledge. Efficiency as a measure of the solutions created is one of the basic characteristics of software and systems. It can be understood in several contexts, so I would like to highlight some of the most important ones. 

Algorithmic efficiency  

A measure of the average execution time necessary for an algorithm to complete work on a set of data... If two algorithms for the same problem are of the same order then they are approximately as efficient in terms of computation. Algorithm efficiency is useful for quantifying the implementation difficulties of certain problems. (John Daintith and Edmund Wright: A Dictionary of Computing)

Every developer has come across this definition in some way. We can consider it optimal use of computational resources, defined as computation time and memory space. Since both those values are quite difficult to compare, that’s why the well-known Big O notation was founded. First, by two German mathematicians, Paul Bachmann and Edmund Landau. Fun fact: the letter O stands for German Ordnung, expressing the order of approximation. That was in the late 1900s. Then, in 1976, a famous professor from Standford University, Donald Kruth, was inspired by it and already existed Big Omega notation and introduced it to computer science.   

From that point, most of us are already familiar with the given table: 

Algorithmic efficiency_Big Omega notation

Those definitions are still valid and extremely helpful in evaluating the complexity of problems in the IT industry.  

ISO/IEC 25010  

So far, we have gathered time and space as two crucial values for efficiency assessment. Let’s not stop yet. In such an informal article, we should at least take a look at a more formal definition proposed by the International Organization of Standardization, most known as ISO. Since, across ages, they introduced several standards, which include efficiency in some form, today I’ll concentrate specifically on one which is strictly coupled to software development: 

 ISO/IEC 25010:2011 and its revised version ISO/IEC 25010:2023.  

ISO/IEC 25010

As we can see from that comprehensive view, performance efficiency plays a vital role, as it has been distinguished as one of 8 software characteristics.  

Performance efficiency: capability of a product to perform its functions within specified time and throughput parameters and efficiently use resources under specified conditions.  

Note 1: Resources can be CPU, memory, storage, and network devices.  

Note2: Resources can include other software products, the software and hardware configuration of the system, energy, and materials  (The International Organization of Standardization: ISO/IEC 25010:2023 – Product Quality Model

We got some additional perspectives and puzzles on the main subject. So far, we have both mathematical and formal, standardized definitions. At this stage, I think an opinion is missing from the perspective of the engineers' workflow when solving problems or domain requirements.  

Productive (efficient?) engineer  

Before discussing this topic further, let’s quickly compare efficiency with fancy productivity. Productivity is about how much you can accomplish, while efficiency is about how well you use your resources to get things done. We can also simplify this by saying that productivity is about quantity, while efficiency is about quality.    

“Productivity is defined as the amount of useful work performed over time. “ (Neal Ford: The Productive Programmer, 2008 ) 

We can also make things a little bit more complicated and add additional variables to our definition.  

Productivity in a software development

Source: Caitlin Sadowski, Thomas Zimmermann: Rethinking Productivity in Software Engineering  

To reach our highest productivity, we should generate the biggest possible output – defined as efficiency by the smallest input, which can be understood as the cost and efficiency of our work.   

Being a productive developer is an important part of the modern engineer skillset because it allows engineers to deliver more value to their teams and businesses. When productive, engineers can meet deadlines, improve quality, and reduce costs. They are also more likely to be satisfied with their work and less likely to burn out.  

Some of the key characteristics of a productive developer include:  

  • Effective time management: Knowing how to plan and organize their work to meet deadlines and avoid burnout.  
  • Strong problem-solving skills: Being able to identify and solve problems quickly and efficiently.  
  • Attention to detail: Being able to catch and fix errors before they cause problems.  
  • Ability to learn new things: Being open to learning new technologies and techniques to stay current with the latest trends.  

By developing these skills, engineers can become more productive and contribute more to their teams and organizations.  

Efficiency in Spring Projects World  

Multi-dimensional definition 

As we’ve noticed, the definition of efficiency appears in different contexts. Therefore, I would like to identify the key functionalities of the framework and assign them to each mentioned context.  

Efficiency in Spring Projects World

 

Cloud-native  

Java 21 and virtual threads  

Traditional threads in Java were expensive and limited the number of concurrent requests a server could handle. Java 21 officially includes virtual threads as part of JDK, which are lighter-weight and more efficient, allowing for millions of threads to be created on the heap. They were originally created under Project Loom. They run on the same threads, which act as carriers for them. This allows servers to handle a much higher volume of requests without sacrificing performance. 

Spring MVC applications 

From Spring framework perspective, virtual threads are lightweight threads that are ideal for Spring MVC because they can handle blocking I/O (I/O refers to Input/Output in the computing world to denote how the communication happens between systems) without incurring the high overhead of traditional threads. Spring MVC can automatically take advantage of virtual threads on servlet containers like Tomcat and Jetty, without requiring any code changes. This feature comes natively with Spring Boot 3.2 and can be enabled via spring configuration based on application.yml. What is worth to mention, Spring WebFlux remains still valid for non-blocking solutions. 

Spring Cloud (native)  

Cloud Native development emphasizes adopting best practices to streamline software delivery and ensure value-driven development. It is based on related 12-factor apps, where development methods align with delivery and operations objectives using declarative programming, monitoring, and management. Spring Cloud supports these development styles by providing a comprehensive set of features that cater to the needs of distributed systems. 

For those unfamiliar with Spring Cloud - it is a set of tools that helps developers build distributed systems quickly and easily. It provides several features that are commonly used in distributed systems, such as configuration management, service discovery, routing, service-to-service calls, load balancing, circuit breakers, distributed messaging, short-lived microservices, and consumer-driven and producer-driven contract testing. Spring Cloud works well in any distributed enterprise application environment, including developers' laptops, bare-metal data centers, and managed platforms like Cloud Foundry or Kubernetes. The second one has been widely popular in the last few years since it provides developers with a scalable distributed framework that manages clusters and applications, making it an excellent choice for workloads that span multiple cloud environments. This flexibility benefits developers who can deploy applications across various cloud platforms. 

GraalVM - an advanced JDK with ahead-of-time native image compilation 

Spring Boot 3.0 introduced native support for GraalVM which replaced earlier developer Spring Native project. This brought huge advantages in terms of reducing the resources used. Java applications compiled ahead of time by GraalVM require less memory and CPU to run. It enables the deployment of lightweight containers that start up in a matter of milliseconds, significantly faster than traditional JVM containers. This reduced startup time and lower memory footprint optimise application infrastructure and ensure peak performance is achieved immediately. It also closely follows new Java features, including virtual threads, providing immediate access to the latest advancements.   

Naturally, there are also some drawbacks since during ahead-of-time (AOT) compilation, it simply removes not needed code. The main trade-offs are:  

  • Native image compilation takes minutes instead of seconds. This can be a significant overhead compared to the JVM, which can compile java classes in seconds.  
  • It requires additional metadata to properly handle reflection, proxies, and other dynamic behaviours of the JVM. This metadata can be generated automatically by Spring project, but it may not be complete for all projects.  
  • Combining Spring AOT transformations and GraalVM native image requires us to freeze the classpath and bean conditions at build time. This means that you cannot change the classpath or the bean conditions at runtime. This must be taken into consideration, since Spring container won't be able to reflect all changes in its context. 

 

JVM Checkpoint Restore  

CRaC is an OpenJDK project that provides a new Java API for checkpoint and restore operations on the HotSpot JVM. It relies on the CRIU project for checkpoint/restore functionality on Linux. It allows you to checkpoint your running JVM, including its memory and state, to disk and restore it later on, potentially on a different machine. This can be useful for saving and restoring the application state and improving cold start performance.  

The CRaC project is still under development, but it has already been adopted by AWS Lambda and IBM OpenLiberty. It is a promising technology that can make JVM applications more efficient and resilient. 

Event-driven  

Event-driven systems align with the ever-evolving landscape of modern businesses, where numerous minor modifications transpire continuously. Spring's ability to handle and utilize events enables developers to construct applications that mirror this dynamic nature, keeping your apps in sync with business operations. Spring framework comprises a comprehensive selection of event-driven solutions, spanning integration, streaming, cloud functions, and data flow functionalities. 

Integration patterns in enterprise applications 

With a dedicated project, Spring Integration, Spring enables using popular and well-established patterns based on enterprise design patterns. It simplifies messaging within web applications and facilitates integration with external systems via declarative adapters, which streamline Spring's existing support for remote messaging and scheduling. It aims to provide a straightforward approach to building enterprise integration solutions while maintaining the separation of concerns, inversion of control, and dependency injection, which are essential concepts for creating maintainable, testable code and also to avoid tight coupling. 

Beyond connecting fine-grained components, it provides a comprehensive collection of channel adapters and gateways for communicating with external systems. Channel Adapters handle one-way integration (sending or receiving), while gateways facilitate request/reply interactions (both inbound and outbound). 

High-level messaging brokers  

Modern software architectures rely on distributed systems, where messaging brokers are crucial in facilitating communication between disparate services. Java Message Service, RabbitMQ, Kafka, and ActiveMQ are widely adopted messaging brokers, each offering distinct features suited for specific applications.   

The Spring Framework provides extensive tools for seamless integration with messaging systems, from simplified JMS API interaction with JmsTemplate to a comprehensive framework for handling asynchronous message exchanges. Spring AMQP offers a similar feature set tailored for AMQP-based messaging. It further simplifies connectivity by providing auto-configuration options for RabbitTemplate and RabbitMQ. Spring WebSocket seamlessly integrates with STOMP messaging, and Spring extends this support with starters and minimal auto-configuration. Additionally, it supports Apache Kafka and Apache Pulsar integration.  

Streaming processing  

Spring Cloud Stream simplifies the creation of message-driven microservices, building upon Spring Boot to generate self-contained, production-grade Spring applications. It seamlessly integrates with Spring Integration to establish connections to messaging brokers, providing vendor-agnostic configuration options while introducing the concepts of persistent publish-subscribe semantics, consumer groups, and partitions.  

The core building blocks of Spring Cloud Stream are:  

  • Destination Binders: The connectors responsible for establishing communication with external messaging systems.  
  • Destination Bindings: The intermediaries that connect external messaging systems to developed application code, both producers and consumers,  
  • Message: The standardized data format utilized by producers and consumers to interact with Destination Binders, enabling communication with other applications via external messaging systems.  

 

On top of that, there is also Spring Cloud Data Flow, which simplifies building and deploying complex data processing pipelines for streaming and batch processing in Cloud Foundry and Kubernetes environments. It provides a toolkit for creating data pipelines using Spring Boot applications, leveraging the already mentioned Spring Cloud Stream and Spring Cloud Task microservice frameworks. Data processing use cases supported by Spring Cloud Data Flow include ETL, import/export, event streaming, and predictive analytics.  

Future of Java in 2024 

We are starting 2024, and yes, Java is not going anywhere. It's still an extremely popular programming language. In a survey conducted by JetBrains at the end of 2023 called The State of Developer Ecosystem among 26348 developers worldwide, 49% of them said they had used Java in the last 12 months. In comparison, the most popular JavaScript had been used by 61%. In addition, as many as 33% declare that it is the primary language they use, which is the highest percentage in this survey. Let's not forget that the JVM family also includes kotlin and scala, among others, which are quite popular. The former is more relevant in our context, as it can be used from 2017 onwards in the Spring framework from version 5.0. 

Spring Boot remains popular  

As for the main framework of today's article - Spring Boot according to a survey on stackoverflow.com  enjoys the approval of almost 14% of surveyed professionals, making it the 6th most popular backend framework and the first based on the JVM.  

In addition, based on public repositories created on github.com, the number of established projects in 2023 is more than 106,000. By comparison, in node.js (which ranked highest in the survey mentioned on stackoverflow.com), it's over 107,000.   

Java and Spring Framework are still very popular tools in the enterprise applications world. This is influenced by rich documentation, years of production experience, and many open-source tools. Spring Boot is still actively developed, and while maintaining opinionated status, it is much easier to follow recommended design and architectural patterns.   

Java community

The number of established projects in 2023 is more than 106,000. By comparison, in node.js (which ranked highest in the survey mentioned on stackoverflow.com), it's over 107,000.   

Java and Spring Framework are still very popular tools in the enterprise applications world. This is influenced by rich documentation, years of production experience, and many open-source tools. Spring Boot is still actively developed, and while maintaining opinionated status, it is much easier to follow recommended design and architectural patterns.   

Summary  

Efficiency is a critical concept in software development, encompassing various aspects such as algorithmic performance, resource utilisation, and developer productivity. The ISO/IEC 25010 standard defines performance efficiency as the ability of a product to execute its functions within specified time and throughput parameters while optimising resource consumption.   

Performance efficiency is addressed through Java 21 virtual threads, lighter-weight alternatives to traditional threads that reduce execution overhead. Further, GraalVM native images enable faster application startup and reduced memory footprint.  

Event-driven development is facilitated by Spring's comprehensive ecosystem, including Spring Integration, messaging brokers, and streaming processing capabilities. It simplifies messaging within applications and facilitates integration with external systems via declarative adapters. A wide range of messaging brokers, including JMS, AMQP, RabbitMQ, Kafka, and Pulsar, are supported. Spring Cloud Stream simplifies message-driven microservices creation, while Spring Cloud Data Flow streamlines complex data processing pipelines for streaming and batch processing in Cloud Foundry and Kubernetes environments.  

Java's enduring popularity is evident in its continued adoption among developers, as evidenced by surveys and project repositories. Spring Boot's popularity is also significant, ranking sixth among backend frameworks and first among JVM-based frameworks. Its rich documentation, extensive production experience, and plethora of open-source web frameworks contribute to its enduring appeal.  

In conclusion, Spring Boot and Java offer a comprehensive suite of features that enhance efficiency across various dimensions of software development. From algorithmic performance optimization to event-driven architectures and enterprise integration patterns, Spring Boot provides a robust foundation for building modern, scalable, and efficient Java applications. Java's continued relevance and Spring Boot's popularity underscore the merits of these technologies in the contemporary software development landscape. 

I hope you enjoyed this brief overview of efficiency in software development and the features that Spring Boot and Java offer to enhance efficiency. Thank you for reading! Stay tuned for more Java and Spring World-related content soon.  

Stay safe and happy coding. 

 

References 

  • Łukasz Bielarczyk: Meanings and interpretations of efficiency in ISO standards; 2022 
  • Maddy Osman: Productivity vs. Efficiency: How To Improve Both at Work,2023 
  • Neal Ford: The Productive Programmer, 2008 
  • Caitlin Sadowski, Thomas Zimmermann: Rethinking Productivity in Software Engineering, 2019 

 

Design, Development, DevOps or Cloud - which team do you need to speed up work on your projects?

Chat with your consultation partners to see if we are a good match.

Jakub Orczyk
Member of the Management Board/ Sales Director VM.PL
Book a free consultation
Jakub Orczyk

Let's arrange a meeting!

We will be happy to visit you in your office. This will allow us to discuss the possibilities of cooperation in person.

Just leave a message and we'll get back to you to arrange a convenient date.

* Please complete all mandatory fields.
Let's arrange a meeting!