What We Mean By "Spring"
The term "Spring" means different things in different contexts. It usually refers to the Spring Framework project, which has later expanded to include various related projects(spring-boot, spring-data, spring-security etc.) over time.
The Spring Framework is split into modules, allowing applications to select the ones they need. The core container modules handle configuration and dependency injection. Additionally, Spring offers support for different application types like messaging, data storage, and web development, including Spring MVC and Spring WebFlux.
Why Do We Need "Spring"
Spring came into being in 2003, before that we had J2EE, EJB etc. which are very complex and bulky in nature. For example, if we need EJB only for Transaction Management for our banking project then we can not just get the transaction management we will have to include entire EJB framework which makes the application bulky and of course EJB and J2EE are very complex.
The above problem is solved by spring by having different modules. For example, If i need spring only for dependency injection then i can just include spring-core in my project or if i need web development then just include spring-web module.
Spring Framework Design Philosophy
When you learn about a framework, it’s important to know not only what it does but what principles it follows. Here are the guiding principles of the Spring Framework:
Provide choice at every level. Spring lets you defer design decisions as late as possible. For example, you can switch persistence providers through configuration without changing your code. The same is true for many other infrastructure concerns and integration with third-party APIs.
Accommodate diverse perspectives. Spring embraces flexibility and is not opinionated about how things should be done. It supports a wide range of application needs with different perspectives.
Maintain strong backward compatibility. Spring’s evolution has been carefully managed to force few breaking changes between versions. Spring supports a carefully chosen range of JDK versions and third-party libraries to facilitate maintenance of applications and libraries that depend on Spring.
Care about API design. The Spring team puts a lot of thought and time into making APIs that are intuitive and that hold up across many versions and many years.
Set high standards for code quality. The Spring Framework puts a strong emphasis on meaningful, current, and accurate Javadoc. It is one of very few projects that can claim clean code structure with no circular dependencies between packages.
Dependency Injection and Inversion of Control
In Java applications, objects work together, but organizing them into a coherent structure is left to developers. While design patterns like Factory, Abstract Factory, etc. helps , they need to be implemented manually. The Spring Framework's Inversion of Control (IoC) component solves this by offering a structured way to integrate components into a complete, usable application. It formalizes design patterns as reusable objects, making applications more robust and maintainable. Many organizations use Spring for this purpose.
In 2004 Martin Fowler questioned the term Inversion of Control (IoC) "what aspect of control are they inverting?" in his site and suggested the name "Dependency Injection" to make it more self-explanatory.
https://martinfowler.com/articles/injection.html
So Inversion of Control (IoC), also called dependency injection (DI), is a way for objects to declare what they need to work with (like other objects) through constructor arguments, factory method arguments, or set properties. Rather than objects managing their dependencies directly, a container handles injecting these dependencies during object creation. It's called "inversion" because it flips the usual control, where objects control their own dependencies. Instead, the container takes charge, making the process more flexible and manageable.
The Spring Framework's IoC container relies on two key packages: org.springframework.beans and org.springframework.context. The BeanFactory interface, found in these packages, offers advanced configuration capabilities to manage various object types. ApplicationContext, a sub-interface of BeanFactory, extends functionality by integrating seamlessly with Spring's AOP features, handling message resources for internationalization, publishing events, and providing application-specific contexts like WebApplicationContext for web applications.
In summary, while BeanFactory offers core configuration and functionality, ApplicationContext enhances it with enterprise-specific features. The ApplicationContext is a complete superset of the BeanFactory.
In Spring, the core objects managed by the Spring IoC container are referred to as beans. A bean is essentially an object that the Spring IoC container instantiates, assembles, and manages. Apart from that, a bean is just like any other object in your application. The relationships between beans, along with their dependencies, are outlined in the configuration metadata used by the container.
Spring Framework Modules
The Core Container in Spring comprises several modules: spring-core, spring-beans, spring-context, spring-context-support, and spring-expression (which provides Spring Expression Language).
The spring-core and spring-beans modules offer the essential features of the framework, including Inversion of Control (IoC) and Dependency Injection. The BeanFactory simplifies object creation and dependency management, allowing you to separate configuration from program logic.
The Context (spring-context) module builds upon the Core and Beans modules, providing access to objects in a framework-like manner similar to a JNDI registry. It supports internationalization, event propagation, resource loading, and context creation (e.g., by a Servlet container). It also integrates with Java EE features like EJB, JMX, and remoting. The ApplicationContext interface is central to this module. Additionally, spring-context-support aids in integrating third-party libraries like caching, mailing, scheduling, and template engines into the Spring application context.
The spring-expression module offers a powerful Expression Language for querying and manipulating object graphs at runtime. It extends the unified expression language specified in the JSP 2.1 specification. The language supports property setting/getting, method invocation, array/collection access, logical/arithmetic operations, named variables, object retrieval from Spring's IoC container, list projection/selection, and common list aggregations.
The spring-aop module offers an Aspect-Oriented Programming (AOP) implementation that follows the AOP Alliance standards. This allows you to define method interceptors and pointcuts, enabling you to cleanly separate functionality within your codebase. With source-level metadata functionality, you can incorporate behavioral information into your code, similar to .NET attributes.
The spring-aspects module integrates with AspectJ, a powerful AOP framework.
The spring-instrument module provides support for class instrumentation and includes classloader implementations designed for specific application servers. For instance, the spring-instrument-tomcat module contains Spring's instrumentation agent for Tomcat servers.
The spring-messaging module helps build messaging-based applications. It introduces core elements like Message, MessageChannel, and MessageHandler from the Spring Integration project. Plus, it offers annotations that connect messages to methods, similar to how Spring MVC handles annotations for web applications.
The Data Access/Integration layer in Spring consists of several modules:
spring-jdbc: Provides a JDBC abstraction layer, reducing the need for tedious JDBC coding and handling database-specific error codes.
spring-tx: Supports both programmatic and declarative transaction management for classes implementing special interfaces and for Plain Old Java Objects (POJOs).
spring-orm: Offers integration layers for popular object-relational mapping (ORM) APIs like JPA, JDO, and Hibernate. You can use these ORM frameworks alongside other Spring features, including declarative transaction management.
spring-oxm: Provides an abstraction layer supporting Object/XML mapping implementations such as JAXB, Castor, XMLBeans, JiBX, and XStream.
spring-jms: Facilitates message production and consumption using the Java Messaging Service (JMS). Since Spring Framework 4.1, it integrates with the spring-messaging module.
These modules streamline various aspects of data access and integration within Spring applications, enhancing productivity and simplifying development tasks.
The Web layer in Spring includes several modules:
spring-web: Offers basic web integration features like multipart file upload, initializing IoC container using Servlet listeners, and a web application context. It also includes an HTTP client and Spring's remoting support for web-related tasks.
spring-webmvc: Also known as the Web-Servlet module, it provides Spring's model-view-controller (MVC) framework for web applications, including RESTful Web Services implementation. Spring MVC ensures a clear separation between domain model code and web forms, integrating seamlessly with other Spring features.
spring-websocket: This module supports WebSocket-based communication in web applications, allowing for real-time, full-duplex communication between clients and servers.
spring-webmvc-portlet: Also known as the Web-Portlet module, it offers the MVC implementation for use in a Portlet environment. It functions similarly to the Servlet-based spring-webmvc module, providing MVC functionality tailored for Portlet environments.
The spring-test module in Spring Framework supports both unit testing and integration testing of Spring components using JUnit or TestNG. It ensures consistent loading of Spring ApplicationContexts and caching of those contexts, making testing more efficient. Additionally, the module offers mock objects that enable you to test your code in isolation, simplifying the testing process.
Logging
Logging is a very important dependency for Spring because a) it is the only mandatory external dependency, b) everyone likes to see some output from the tools they are using, and c) Spring integrates with lots of other tools all of which have also made a choice of logging dependency.
The mandatory logging dependency in Spring is the Jakarta Commons Logging API (JCL) which is commons-logging
(the canonical implementation of JCL).
The nice thing about commons-logging
is that you don’t need anything else to make your application work. It has a runtime discovery algorithm that looks for other logging frameworks in well known places on the classpath and uses one that it thinks is appropriate (or you can tell it which one if you need to). If nothing else is available you get pretty nice looking logs just from the JDK (java.util.logging or JUL for short). You should find that your Spring application works and logs happily to the console out of the box in most situations, and that’s important.