Spring 的依赖注入原理

Spring 的依赖注入(Dependency Injection,DI)是其核心特性之一,它的主要作用是管理对象之间的依赖关系,降低对象之间的耦合度,提高代码的可维护性和可测试性。其原理如下:

一、基本概念

  1. 控制反转(Inversion of Control,IoC)
    • 在传统的编程方式中,对象的创建和依赖关系的管理通常由对象自己负责。而在 Spring 中,这种控制权被反转了,对象的创建和依赖关系的管理由 Spring 容器负责。这就是控制反转的概念。
  2. 依赖关系
    • 一个对象在运行时可能需要依赖其他对象来完成其功能。例如,一个业务服务类可能需要依赖一个数据访问对象(DAO)来访问数据库。这种依赖关系可以通过构造函数、Setter 方法或者字段注入的方式进行注入。

二、实现方式

  1. 基于 XML 配置的依赖注入
    • 在 XML 配置文件中,开发者可以定义 Bean(即由 Spring 容器管理的对象)以及它们之间的依赖关系。例如:
xml 复制代码
<beans>
    <bean id="userDao" class="com.example.dao.UserDaoImpl">
    </bean>
    <bean id="userService" class="com.example.service.UserServiceImpl">
        <property name="userDao" ref="userDao">
        </property>
    </bean>
</beans>
  • 在上面的配置中,定义了两个 Bean:UserDaoImplUserServiceImplUserServiceImpl通过 Setter 方法注入了对UserDaoImpl的依赖。
  • Spring 容器在启动时会读取这个配置文件,创建并管理这些 Bean。当需要创建UserServiceImpl对象时,Spring 容器会自动查找名为userDao的 Bean,并将其注入到UserServiceImpl对象中。
  1. 基于注解的依赖注入
    • Spring 提供了一系列注解来简化依赖注入的配置。例如,@Autowired注解可以自动注入对象的依赖关系。以下是一个示例:
java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class UserServiceImpl implements UserService {

    @Autowired
    private UserDao userDao;

    //...
}
  • 在这个例子中,UserServiceImpl类被标注为@Service,表示这是一个业务服务类。@Autowired注解用于自动注入UserDao对象。Spring 容器在扫描到这个类时,会自动创建UserDao对象,并将其注入到UserServiceImpl对象中。
  1. 基于 Java 配置类的依赖注入
    • 除了 XML 配置和注解,Spring 还支持使用 Java 配置类来定义 Bean 和它们之间的依赖关系。例如:
java 复制代码
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class AppConfig {

    @Bean
    public UserDao userDao() {
        return new UserDaoImpl();
    }

    @Bean
    public UserService userService() {
        UserServiceImpl userService = new UserServiceImpl();
        userService.setUserDao(userDao());
        return userService;
    }
}
  • 在这个配置类中,使用@Bean注解定义了两个方法,分别返回UserDaoUserService对象。在userService方法中,手动注入了对UserDao的依赖。Spring 容器在启动时会扫描这些配置类,并根据配置创建和管理 Bean。

三、工作流程

  1. 容器启动
    • Spring 容器在启动时,会读取配置信息(XML 配置文件、注解、Java 配置类等),并根据这些信息创建和初始化 Bean。
  2. 依赖解析
    • 对于每个 Bean,Spring 容器会检查其依赖关系。如果一个 Bean 有依赖其他 Bean 的需求,Spring 容器会查找并创建相应的依赖 Bean。
  3. 依赖注入
    • 当所有的依赖 Bean 都创建完成后,Spring 容器会将这些依赖 Bean 注入到需要它们的 Bean 中。注入的方式可以是通过构造函数、Setter 方法或者字段注入。
  4. 对象使用
    • 开发者可以从 Spring 容器中获取已经创建并注入了依赖关系的 Bean,并使用这些对象来完成业务逻辑。

总之,Spring 的依赖注入原理是通过控制反转将对象的创建和依赖关系的管理交给 Spring 容器,然后通过各种配置方式(XML 配置、注解、Java 配置类)来定义 Bean 和它们之间的依赖关系,最后在容器启动时自动创建和注入这些依赖关系,从而实现了对象之间的松散耦合。

相关推荐
martinzh10 分钟前
Spring AI 项目介绍
后端
Bug退退退12316 分钟前
RabbitMQ 高级特性之重试机制
java·分布式·spring·rabbitmq
小皮侠17 分钟前
nginx的使用
java·运维·服务器·前端·git·nginx·github
前端付豪20 分钟前
20、用 Python + API 打造终端天气预报工具(支持城市查询、天气图标、美化输出🧊
后端·python
爱学习的小学渣22 分钟前
关系型数据库
后端
武子康25 分钟前
大数据-33 HBase 整体架构 HMaster HRegion
大数据·后端·hbase
前端付豪25 分钟前
19、用 Python + OpenAI 构建一个命令行 AI 问答助手
后端·python
凌览26 分钟前
斩获 27k Star,一款开源的网站统计工具
前端·javascript·后端
Zz_waiting.29 分钟前
Javaweb - 10.4 ServletConfig 和 ServletContext
java·开发语言·前端·servlet·servletconfig·servletcontext·域对象
全栈凯哥29 分钟前
02.SpringBoot常用Utils工具类详解
java·spring boot·后端