Spring Framework: From the very beginning

From Java creation and J2EE components to Spring's architecture

Iran Macedo
13 min readDec 6, 2021
Photo by NeONBRAND on Unsplash

Disclaimer

This is part of my journey to deeply understand Spring and its related technologies. It's a 3000+ word article so if you want to do better use of this, don't read it on a mobile screen. Also, bookmark this so it can be a reference whenever you need it. It's been an awesome reference for me.

This article covers

  • Java and JVM historic background
  • J2EE history and architecture
  • J2EE components description
  • Spring history and architecture
  • Spring's components description

I have always liked to search for the true inspiration and history of something I desire to truly understand. I think this is the best way for knowing something. For software development, understanding the history of the technologies you're using is gaining the power to best use them. We are going to check a little of history with Java and JVM to understand in which scenario J2EE was created and why is it so important to Spring.

Background

Born in the mid-90s, Java was a language created by Sun Microsystems Inc whose main idea was the possibility of using it for any platform or media through the Java Virtual Machine. “Write Once, Run Anywhere” (WORA) was divulged as an ideal for the applications of the future. In a time of large production and social acceptance of various media as Personal computers (PCs), Palmtops, and cell phones, the possibility of developing just one code base being executed for all types of media emerged as a gigantic revolution. Let’s remember that the technologies of the time were directly dependent on the type of media executed as they were compiled languages.

The most used languages ​​before Java in the 90s were: C, C++, Fortran, Visual Basic, Ada, Pascal, among others. They all needed a compiler to run. As the compiler transforms the source code into machine-level operations this makes it intrinsically dependent on the platform (or machine) that will run the application. Because languages ​​like Assembly had specific commands to be executed in specific hardware architectures. A particular compiler was made for particular hardware. But then how did Sun Microsystems allow one code base to become the same for all infrastructures?

The big innovation brought by Sun and Java was the JVM (Java Virtual Machine). JVM is a virtual machine whose purpose is to be the interface between the Java application and the real machine’s hardware. Therefore, it was not necessary to know the hardware specifications to develop a Java application, as topics such as memory management (garbage collector) or concurrent processing were led by the JVM, taking these responsibilities present in compiled languages ​​from the time out of the developer’s hands. The JVM was responsible for compiling the base code and transforming it into bytecode, a format that was recognized only by the JVM itself. Once the bytecode is ready, it is validated if there are no faults and then executed. Despite critics and disbelievers that this change wouldn’t be the future of software development, companies at the time were massively adopting from the perspective of the productive increase of the development team.

Thanks to this versatility, Java had three well-known environments: JSE (Java Standard Edition — used in most cases for native applications and other computers), JEE (Java Enterprise Edition — used for network, internet, and intranet communication), and JME (Java Micro Edition — dedicated to the development of mobile applications such as PDA and mobile). J2EE or JEE is an important part of Spring development as we dive into J2EE.

In order to understand Spring's characteristics and functionalities are necessary to spend some time analyzing and understanding what is Java Enterprise Edition and how does it work.

Java Enterprise Edition (J2EE)

Java2 Enterprise Edition (J2EE or JEE) was massively adopted by the market in the early 2000s, a scene where companies needed their applications connected and available on the Internet for the entire world to be able to access, do online shopping, among other activities. According to Oracle’s documentation, J2EE is an environment with a set of standard specifications that describe application components, APIs, runtime containers, and services of an application server. The platform’s purpose is to handle the lower-level complexity of the application allowing developers to focus on the business logic itself. J2EE was used to develop web applications with HTML pages or even specific applets.

Some of the key benefits are:

  1. It provides one of the key functionality of cross-platform portability.
  2. Like any other Java-based technology, open-source libraries are available easily for the common developer.
  3. Handling some big enterprise-level applications for deploying on the server-side easily.
  4. Always maintained and covered the maximum global W3C Standard by J2EE technologies.
  5. Business logic is organized into reusable components and the J2EE server provides underlying services in the form of a container for every component type.

But, how does J2EE works underneath? Let’s analyze each part to understand how it worked.

Architecture & Components

J2EE was built to use a multi-tier (generally considered 3 tiers) distributed application model to manage the configurations and infrastructure: Client, Middle, and Enterprise data tier.

J2EE Multi-tier interaction

Client tier

The client tier consists of user programs that interact with the user for request and response. Usually, they are located in a different machine from the server. Client tier prompts the user inputs into user requests then forwarded to the J2EE server then processed results returned to the client. A client can be a web browser, standalone application, or server that runs on a different machine such as Applets, GUI applications, among others.

Middle tier

The middle tier is also known as the server-tier where enterprise beans and the web service encapsulates distributable business logic for the application. Consisted basically of web components such as Servlets, Java Server Pages, or a Java Standalone application.

Web Components

JSP is a server-side technology that allows the creation of dynamic and platform-independent methods for web-based applications. It benefits from all Java APIs including Database communication (JDBC) to access enterprise databases (In general, accessing a database from a JSP page is a bad idea). The main idea is to handle dynamic content. This helps programmers to embed Java code into JSP tags that were rendered to the client on the web.

Dynamic content was very accepted by the developers and companies. Today, we have lots of frameworks javascript working with this principle.

Being very simplistic, Servlet is a java program that runs on a web server used to make or create dynamic applications and web pages extending server capabilities.

Let’s follow how it would happen.

  1. A web browser through the GET HTTP method requests a page to a server.
  2. The server receives, validates the request (in detail in the next sessions), and communicates with the servlet which page needs to be returned.
  3. The Servlet (web app) takes the requested page, processes the dynamic content needed, and gives it back to the server.
  4. The server then returns the page to the browser with the content ready to be read by the browser.

EJB Component

EJB stands for Enterprise Java Beans meaning the components that handle business code to solve particular business domains such as banking, management, finance, among others present in this business tier. It can

  • Receive data from client processes and, if necessary, send it to the enterprise information system for storage.
  • Retrieve data from storage, process it, and send it back to the client tier.

There are 3 kinds of beans:

  • Session bean: Used for a conversation with the client. As the name says, it is similar to an interactive session, not shared but individual for each client and not persistent. When the client terminates, its session bean appears to terminate and is no longer associated with the client. We can have stateless or stateful session beans.

Because stateless session beans can support multiple clients, they can offer better scalability for applications that require large numbers of clients. Typically, an application requires fewer stateless session beans than stateful session beans to support the same number of clients.

  • Entity bean: Represents a business object, typically with an underlying table in a particular persistent storage mechanism (relational database). Once the server shutdowns or the client finishes its execution, entity bean data is preserved. Entity beans are persistent, allow shared access, have primary keys, and may participate in relationships with other entity beans.

There are two types of persistence for entity beans: bean-managed and container-managed. With bean-managed persistence, the entity bean code that you write contains the calls that access the database. If your bean has container-managed persistence, the EJB container automatically generates the necessary database access calls. The code that you write for the entity bean does not include these calls.

  • Message Driven Bean: The message bean combines the properties of Session Bean and JMS using the asynchronous nature of a JMS listener with the advantages of the EJB container.

Data tier

Also known as the Enterprise Information System (EIS), it consists of database servers, enterprise resource planning systems, and other data sources. These resources are typically located on a separate machine than the J2EE Server and accessed by components on the business tier.

  • Java Database Connectivity API (JDBC): The Java API that manages connecting to a database, issuing queries and commands, and handling result sets obtained from the database released as part of Jaa 1.1 in 1997. JDBC is the common API that your application code interacts with. Beneath that is the JDBC-compliant driver for the database you are using.
  • Java Persistence API: JPA is a standard for Object Relational Mapping. This is a technology that allows you to map between objects in code and database tables. This can “hide” the SQL from the developer so that all they deal with are Java classes, and the provider allows you to save them and load them magically.
  • Java Connector Architecture (JCA): A JCA Resource Adapter serves as a software driver for an EI system by providing standardized means to integrate with Enterprise Integration Systems (EIS) such as Enterprise Resource Planning Systems (SAP, PeopleSoft, Baan), Transaction Monitors (CICS, Tuxedo) and Database Management Systems (Oracle, Sybase).
  • Java Transaction API (JTA): The Java™ Transaction API (JTA) allows applications to perform distributed transactions, that is, transactions that access and update data on two or more networked computer resources. The JTA specifies standard Java interfaces between a transaction manager and the parties involved in a distributed transaction system: the application, the application server, and the resource manager that controls access to the shared resources affected by the transactions.

Despite J2EE bringing a lot of innovation and ease to the way, developers write their code, over time some problems have arisen with the widespread adoption of J2EE.

  1. Writing code became more and more complex, as developers had to draw on countless XML files and work with several different types of configurations.
  2. Components proved exceedingly frustrating to work with, as developers had to hard-code all the dependencies each component required.
  3. All of Java EE’s features were supported and thus needed to be configured. This led to very bloated code that slowed down applications.

As an answer to the complexity of creating and maintaining J2EE applications. Rod Johnson, Australian consultant developer, at the release of one of his best practices books with J2EE, called attention to the benefit of using dependency injection and POJOs in J2EE applications. His work included nearly 30k lines of code showing how this would work in J2EE. The community at the time loved the idea and started to adopt Rod’s code in their applications. In 2004 under the Apache license, the first production version of this code called Spring was released. It’s important to note that for Rod Johnson and his other co-authors Spring Framework was not created to be a competitor to J2EE but a complement.

Spring

The way J2EE inspired Spring's creation can be observed in Spring's design philosophy with emphasis on items 1 and 2.

  1. Provide choice at every level. Spring lets you defer design decisions as late as possible. Despite J2EE in which required lots of configuration beforehand.
  2. Accommodate diverse perspectives. Spring embraces flexibility and is not opinionated about how things should be done.
  3. Maintain strong backward compatibility.
  4. Care about API design.
  5. Set high standards for code quality

The Spring programming model does not embrace the Java EE platform specification; rather, it integrates with carefully selected individual specifications from the EE umbrella making it versatile and lightweight for developers and maintainers such as:

Spring Architecture

Let's have a look at Spring architecture

Spring's architecture

Core Container

  • Core: Let's define here container as a group of one or more modules. The Framework's heart is the Core Container where resides the base class and tools and everything was built upon. Zooming in further to the core module of the core container we should see the very base of Spring Framework, the behaviors that made outstand from J2EE: Dependency Injection and Inversion of Control. No matter which type of Spring Application you are building, you will always have direct or indirect dependency over Spring Core. This is the base.

In software engineering, dependency injection is a technique in which an object receives other objects that it depends on, called dependencies. And, Inversion of Control (IoC) means to create instances of dependencies first and latter instance of a class (optionally injecting them through constructor), instead of creating an instance of the class first and then the class instance creating instances of dependencies.

  • Bean: Spring bean is a module responsible to manage beans. Remember EJB? Beans are Java classes that represent something to the application. The Spring Bean module has a BeanFactory which creates bean instances, resolves bean to bean dependencies, and auto wires the beans based on the name, or type. The BeanFactory is a sophisticated implementation of the factory pattern. It removes the need for programmatic singletons and allows you to decouple the configuration and specification of dependencies from your actual program logic.
  • Context: Most of the time the Spring Context is started when a Spring Application starts and is hence called as ApplicationContext. Context module is a means to access objects in a framework-style manner that is similar to a JNDI registry. The Context module inherits its features from the Beans module and adds support for internationalization (using, for example, resource bundles), event-propagation, resource-loading, and the transparent creation of contexts by, for example, a servlet container (Checkout the servlet definition on J2EE section).
  • Expression language: A powerful expression language used for querying and manipulating an object graph at runtime. An example of this typical use is the integration of SpEL into creating XML or annotated-based bean definitions. Despite the fact it is a Spring tool, it's not tied to Spring being possible to manipulate it alone.

Web Container

  • Web and Servlet: Provides the features for building web applications such as multipart file-upload functionality and the initialization of the IoC container using servlet listeners and a web-oriented application context. Spring Web provides a Web Application Context that is similar to the context seen in the Core container. The Web-Servlet module contains Spring’s model-view-controller (MVC) implementation for web applications. Spring’s MVC framework provides a clean separation between domain model code and web forms and integrates with all the other features of the Spring Framework.
  • Struts: The Web-Struts module contains the support classes for integrating a classic Struts web tier within a Spring application. Note that this support is now deprecated as of Spring 3.0
  • Portlet: The Web-Portlet module provides the MVC implementation to be used in a portlet environment and mirrors the functionality of the Web-Servlet module.

Data Container

The Data Access/Integration layer consists of the JDBC, ORM, OXM, JMS, and Transaction modules. We already have covered JDB, JMS, and JTA (Transaction modules) in the J2EE section. Also, we've already mentioned them as some of the protocols Spring brought from the Enterprise environment. So let's provide more information to ORM and OXM.

  • ORM: Object-relational mapping (ORM) module provides integration layers for popular ORMs APIs, including JPA, JDO, Hibernate, and iBatis. Using the ORM package the developer can focus only on mapping the relational database aspects with the code and raw operations and configurations are done by the module with all of the other features Spring offers, such as the simple declarative transaction management feature.
  • OXM: It provides an abstraction layer that supports Object/XML mapping implementations for JAXB, Castor, XMLBeans, JiBX, and XStream.

Other modules

  • AOP and Aspects: An Aspect is any secondary task which an object needs to perform. Each object in Java has a dedicated responsibility apart from this it may have to do some secondary things like logging, or exception handling. Aspect-Oriented Programming provides a mechanism for taking such secondary responsibilities out of the objects and giving them to proxy objects which doubles the original objects. Aspect-oriented programming implementation allows you to define, for example, method-interceptors and pointcuts to cleanly decouple code that implements functionality that should be separated. Using source-level metadata functionality you can also incorporate behavioral information into your code. For example, check out for controller advisors. We have learned what is Aspect-Oriented Programming. Spring Aspects provides a uniform way of integrating with other Aspect-Oriented Programming implementations like AspectJ.
  • Instrumentation: The Spring Instrumentation module provides support for class instrumentation in certain application servers. The instrumentation is used for monitoring the performance of an application. It monitors various objects to diagnose application problems and log them.
  • Testing: The Test module supports the testing of Spring components with JUnit or TestNG. It provides consistent loading of Spring ApplicationContexts and caching of those contexts. It also provides mock objects that you can use to test your code in isolation.

Check out more about testing containers in this video

Conclusion

With Spring Java Web Development evolved a lot throughout the 2000s. The way to build complex and robust web applications became faster and with a lot less complexity due to hard configuration choices to be made in J2EE. But it's still important to know and compare how these two environments were built to comprehend applications that use both and better handle J2EE to Spring's migration.

Spring started to gain real popularity in 2013 when the Spring Boot project was released but this is a topic for a whole different article where we will touch on Application Servers and other stuff.

More references:

https://www.amitph.com/spring-framework-architecture/

Hi everyone, my name is Iran Macedo and I'm a Brazillian consultant software engineer working for Avenue Code in Brazil. Any comments, hints, or additional information is very welcome. Feel free to do so.

Don't forget to share!
Linkedin: https://www.linkedin.com/in/iran-macedo-bezerra-neto/
Twitter: @IranMacedo3
iranmacedo.bneto@gmail.com

--

--

Iran Macedo

A writer to himself. A curious, challenger lover Software Developer at Avenue Code trying to improve my abilities and available to share knowledge