The Spring framework is an open source Java enterprise application development framework. Its purpose is to simplify the development of enterprise applications and reduce the difficulty of development. The Spring framework includes many modules, such as: core container, data access/integration, Web development, AOP (aspect-oriented programming), messaging, testing and integration, etc. In this chapter, we will introduce the core components and functions of the Spring framework in detail, and use examples to help you better understand.
9.1.1. Spring core container
The core container is the foundation of the Spring framework, and it mainly includes the following modules:
- Spring Core : Provides the basic components of the framework, such as dependency injection (DI) and inversion of control (IoC).
- Spring Beans : Provides BeanFactory for managing objects (Bean) in the application.
- Spring Context : Built on the Core and Beans modules, it provides more advanced functions, such as internationalization, event propagation, etc.
- Spring Expression Language (SpEL) : A powerful expression language for querying and manipulating object graphs at runtime.
9.1.2. Dependency Injection (DI) and Inversion of Control (IoC)
Dependency injection and inversion of control are the core concepts of the Spring framework, and they help us achieve decoupling and modularization.
Inversion of Control (IoC) : The dependencies between objects are separated from the code, and the container (such as the Spring container) is responsible for the creation of objects and the maintenance of dependencies.
Dependency Injection (DI) : It is a way to implement IoC, by passing (injecting) the dependent object into the object that needs it, so as to achieve decoupling between objects.
9.1.2.1. Dependency Injection Example
Let's say we have a TextEditor
class that needs one SpellChecker
to check for typos. Without dependency injection, our code might look like this:
class SpellChecker {
// ... SpellChecker的实现 ...
}
class TextEditor {
private SpellChecker spellChecker;
public TextEditor() {
spellChecker = new SpellChecker();
}
// ... TextEditor的实现 ...
}
In this case, TextEditor
the class directly depends on SpellChecker
the class, which leads to tight coupling. We can use dependency injection to solve this problem:
class SpellChecker {
// ... SpellChecker的实现 ...
}
class TextEditor {
private SpellChecker spellChecker;
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
// ... TextEditor的实现 ...
}
Now, TextEditor
instead of directly depending on SpellChecker
the class, the class receives an instance through the constructor SpellChecker
. This way, we can TextEditor
provide different SpellChecker
implementations for it without modifying the class. This is the basic idea of dependency injection.
9.1.3. Spring Bean
In the Spring framework, we refer to the objects of the application as beans. Beans are objects instantiated, assembled and managed by the Spring IoC container. We can configure and manage beans through XML or Java annotations.
9.1.3.1. Configuring Beans Using XML
The following is a simple XML configuration file for defining one SpellChecker
and one TextEditor
beans:
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd">
<bean id="spellChecker" class="com.example.SpellChecker"></bean>
<bean id="textEditor" class="com.example.TextEditor">
<constructor-arg ref="spellChecker"></constructor-arg>
</bean>
</beans>
In this configuration file, we define two Beans: spellChecker
and textEditor
. Beans are injected into beans textEditor
via tags . In the application, we can get and use these beans with:<constructor-arg>
spellChecker
ApplicationContext
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new ClassPathXmlApplicationContext("beans.xml");
TextEditor textEditor = (TextEditor) context.getBean("textEditor");
// ... 使用textEditor对象 ...
}
}
9.1.3.2. Configuring Beans Using Java Annotations
In addition to using XML to configure beans, we can also use Java annotations. Here is a simple example:
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
@Configuration
public class AppConfig {
@Bean
public SpellChecker spellChecker() {
return new SpellChecker();
}
@Bean
public TextEditor textEditor() {
return new TextEditor(spellChecker());
}
}
class SpellChecker {
// ... SpellChecker的实现 ...
}
class TextEditor {
private SpellChecker spellChecker;
@Autowired
public TextEditor(SpellChecker spellChecker) {
this.spellChecker = spellChecker;
}
// ... TextEditor的实现 ...
}
In this example, we have used @Configuration
and @Bean
annotations to define beans. @Autowired
Annotations are used to automatically inject SpellChecker
beans into TextEditor
class constructors. In the application, we can AnnotationConfigApplicationContext
get and use these beans with:
import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class MainApp {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
TextEditor textEditor = context.getBean(TextEditor.class);
// ... 使用textEditor对象 ...
}
}
9.1.4. Other Spring features and modules
The Spring framework also includes many other features and modules, such as data access/integration (including JDBC and ORM support), web development (including Spring MVC and WebFlux), AOP (aspect-oriented programming), etc. In actual project development, we usually use these functions and modules to simplify development work and improve development efficiency.
Summarize
In this section, we introduce the core concepts and functions of the Spring framework, including core containers, dependency injection, inversion of control, Bean configuration and management, etc. Through examples, we show how to use the Spring framework to achieve decoupling and modularization. In actual project development, you need to choose appropriate functions and modules according to actual needs. I hope this chapter can help you better understand and learn the Spring framework. Recommended reading: