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 和它们之间的依赖关系,最后在容器启动时自动创建和注入这些依赖关系,从而实现了对象之间的松散耦合。

相关推荐
WANGWUSAN669 分钟前
Python高频写法总结!
java·linux·开发语言·数据库·经验分享·python·编程
Yvemil79 分钟前
《开启微服务之旅:Spring Boot 从入门到实践》(一)
java
forNoWhat17 分钟前
java小知识点:比较器
java·开发语言
西洼工作室24 分钟前
【java 正则表达式 笔记】
java·笔记·正则表达式
40岁的系统架构师26 分钟前
1 JVM JDK JRE之间的区别以及使用字节码的好处
java·jvm·python
皓木.26 分钟前
(自用)配置文件优先级、SpringBoot原理、Maven私服
java·spring boot·后端
舞者H29 分钟前
启动异常:Caused by: java.lang.IllegalStateException: Failed to introspect Class
java
代码中の快捷键30 分钟前
java开发面试有2年经验
java·开发语言·面试
壹佰大多32 分钟前
【spring-cloud-gateway总结】
java·spring·gateway
CodeChampion33 分钟前
60.基于SSM的个人网站的设计与实现(项目 + 论文)
java·vue.js·mysql·spring·elementui·node.js·mybatis