Spring
The Spring Framework is divided into modules, the heart of which are the modules of the core container, which includes a configuration model and a dependency injection mechanism. Spring also has modules supporting different application architectures such as messaging, transactional data and persistance, and web. It also has the Servlet-based Spring MVC web framework.
Servlets
Jakarta (formerly Java) Servlets are Java classes in Jakarta EE that conform to the Jakarta Servlet API (found in javax.servlet
), which specifies how classes respond to requests, typically extending the HttpServlet
class, which is a subclass of GenericServlet
. Ultimately, a servlet is an object that receives a request and responds to it.
Servlet are deployed and run by web containers, which manage their lifecycle, map specific URLs to them, and ensuring access rights.
Servlets have three central methods: init
, service
, and destroy
.
Spring
Spring was first written in 2003 as a response to the complexity of the early J2EE specifications. Today the Spring framework integrates with individual specifications from the traditional EE umbrella, such as the Servlet API, the WebSocket API, Concurrency Utilities, the JSON Binding API, Bean Validation, and others. It also optionally supports the Dependency Injection and Common Annotations specs in lieu of the Spring-specific alternative mechanisms.
Spring 6.0 has been upgraded to Jakarta EE 9, Tomcat 10.1, Jetty 11, Undertow 2.3 and the Hibernate ORM 6.1.
Core Technologies
The IoC Container
The Spring Framework implements the Inversion of Control (IoC) principle. Dependency Injection (DI) is a specialized form of IoC where objects define their dependencies only through constructor arguments, arguments to a factory method, or properties that are set on an object instance after it's constructed or returned from a factory. The IoC container then injects those dependencies when it creates the bean. It's called "inversion" because it's the opposite of the bean itself controlling the instantiation of it's dependencies itself. A bean is a Java object that is instantiated, assembled, and managed by a Spring IoC container.
org.springframework.beans
and org.springframework.context
are the main packages forming the basis of Spring's IoC container. The BeanFactory
interface provides a configuration mechanism capable of managing any type of object, and ApplicationContext
, a sub-interface of BeanFactory
, has some additional baked-in nice features. BeanFactory
provides the configuration framework and basic functionality and ApplicationContext
adds more entrprise-specific functionality.
Containers
org.springframework.context.ApplicationContext
is an interface representing the Spring IoC container and is responsible for instantiating, configuring, and assembling beans. It receives instructions on which components to manage by reading configuration metadata, which can be in annotated component classes, configuration classes with factory methods, or external XML or Groovy scripts.
In core Spring, the most commonly used implementations of ApplicationContext
are AnnotationConfigApplicationContext
or ClassPathXmlApplicationContext
. Most of the time you won't need to instatiate any instances of a Spring IoC container-- for a plain old web app, a simple boilerplate web descriptor XML file will do it for you, and in Spring Boot the application context is implicitly bootstrapped for you based on common conventions.
Configuration Metadata
Spring consumes configuration metadata that instructs it on how to instantiate, configure, and assemble the objects in your application. Configuration consists of one or more bean definition for the container to manage. It can come via Java, through annotations, or in <bean>
elements (that specify the class name) in an external XML configuration file.
For XML-based configuration, the locations of the XML resources need to be passed to the constructor of a ClassPathXmlApplicationContext
object that lets the container load the configuration files:
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
You can also use multiple XML files by linking additional ones using an <import>
tag.
The Container
ApplicationContext
maintains a registry of beans and their dependencies, which can be queried with the getBean
method:
// create and configure beans
ApplicationContext context = new ClassPathXmlApplicationContext("services.xml", "daos.xml");
// retrieve configured instance
PetStoreService service = context.getBean("petStore", PetStoreService.class);
// use configured instance
List<String> userList = service.getUsernameList();
You could also use a GenericApplicationContext
with reader delegates, such as XmlBeanDefinitionReader
for XML files, like:
GenericApplicationContext context = new GenericApplicationContext();
new XmlBeanDefinitionReader(context).loadBeanDefinitions("services.xml", "daos.xml");
context.refresh();
Ideally, your application code never uses getBean
, ideally Spring's dependency injection and declaring the dependencies between your beans through metadata should take care of things for you.