spring-IOC、DI

IOC控制反转是什么?

传统开发:开发者主动 new 创建对象、管理依赖;

控制反转:把对象的创建、生命周期管理、依赖装配交给 Spring 容器,控制权从代码转移到容器,所以叫反转。

IoC 容器里到底装了什么?(Bean 与 BeanFactory)

Spring 的 IoC 容器本质上是一个超级工厂,它里面装满了由 Spring 管理的 Java 对象,这些对象统称为 Bean。

容器的核心接口是:

  • BeanFactory:Spring 最底层的 IoC 容器,提供最基础的管理功能(延迟加载)。

  • ApplicationContext(应用上下文):它是 BeanFactory 的子接口,功能更强大(支持国际化、事件发布、AOP 集成等),我们在实际开发中用的就是它。

DI(Dependency Injection)依赖注入

在容器中建关系的整个过程是,称为依赖注入。

依赖注入它是实现 IoC 的一种主要方式。

例如:

复制代码
@Servicepublic class UserService {


    private final UserDao userDao;


    public UserService(UserDao userDao) {

        this.userDao = userDao;

    }

}

Spring 创建 UserService 时发现:

复制代码
UserService

      ↓

需要 UserDao

      ↓

IoC 容器查找 UserDao Bean

      ↓

创建/获取 UserDao

      ↓

注入 UserService

Spring 是怎么知道哪些对象需要管理的?

1. 注解扫描

例如:

复制代码
@Component
public class UserDao {

}


@Service
public class UserService {

}


@Controller
public class UserController {

}

Spring 启动时进行组件扫描,发现这些类以后,把它们注册到 IoC 容器。

2. @Bean

也可以手动注册:Spring 会把返回的对象放入 IoC 容器。

复制代码
@Configurationpublic class AppConfig {

    @Bean

    public UserService userService() {

        return new UserService();

    }

}

IoC 是怎么实现的?

Spring 主要通过 IoC 容器实现控制反转。项目启动时,Spring 会扫描 @Component、@Service、@Repository、@Controller 等组件,解析 Bean 定义并创建 Bean,保存到 IoC 容器中。当某个 Bean 依赖其他 Bean 时,Spring 根据依赖关系进行自动装配和注入,例如通过 @Autowired、@Resource 或构造器注入完成依赖关系建立。

复制代码
Spring 启动

    ↓

加载配置

    ↓

组件扫描

    ↓

找到 @Component、@Service 等组件

    ↓

解析 Bean 定义

    ↓

创建 Bean

    ↓

处理 Bean 依赖

    ↓

依赖注入

    ↓

初始化 Bean

    ↓

放入 IoC 容器

    ↓

业务代码获取并使用 Bean

降低耦合解析

没有 IoC 时(高耦合):

复制代码
public class UserService {

    // 自己主动 new 实现类,写死了

    private UserDao userDao = new MySqlUserDao();

    public void doSomething() {

        userDao.save();

    }

}

如果要把 MySqlUserDao 换成 OracleUserDao,必须修改 UserService 的源码。

使用 Spring IoC 后(低耦合):

复制代码
@Service
public class UserService {

    @Autowired // 由容器把合适的实现注入进来

    private UserDao userDao;

    public void doSomething() {

        userDao.save();

    }

}


@Repository
public class OracleUserDao implements UserDao { ... }

现在,UserService 只依赖 UserDao 接口。至于容器注入的是 MySqlUserDao 还是 OracleUserDao,完全由配置决定,UserService 的源码无需改动。

相关推荐
Nebula_g1 小时前
JavaSE加强:IO流
java·开发语言·windows·stream·javase
rannn_1111 小时前
JVM 面试题:类加载过程详解(附高频考点)
java·jvm·后端
程序猿乐锅5 小时前
从0-1一文详解RabbitMQ
java·分布式·后端·中间件·rabbitmq·ruby
考虑考虑8 小时前
JDK26中的List.ofLazy()
java·后端·java ee
小蒜学长8 小时前
基于SpringBoot的公寓报修管理系统的设计与实现(代码+数据库+LW)
java·spring boot·后端·公寓报修管理系统·多角色协同
for_ever_love__8 小时前
MySQL 主从复制讲透:binlog 原理、搭建步骤与读写分离
java·数据库·mysql·binlog·读写分离·原理·主从复制
小π军11 小时前
操作系统面试题
java·linux·服务器
倔强的石头10611 小时前
应用账号最小权限实践:读写账号、报表账号、运维账号分层
java·运维·开发语言
Shaoshing11 小时前
ThreadLocal
java·jvm·threadlocal