Spring Boot 是如何简化 IoC 的配置的?

首先Spring Boot 并没有发明新的 IoC 理论,它做的也不是替换掉 Spring IoC 容器。相反,Spring Boot 是 Spring IoC 思想的实践者和简化者。它通过**"约定优于配置"(Convention over Configuration)**的理念,将原本繁琐的 IoC 配置工作降到了最低。

我们来对比一下"没有 Spring Boot 的时代"(纯 Spring 框架)和"有了 Spring Boot 之后"的区别。


1. 没有 Spring Boot 的时代(纯 Spring 框架)

在 Spring Boot 出现之前,要搭建一个基于 Spring 的 Web 应用,你需要手动完成大量 IoC 相关的配置工作:

a. 繁琐的 XML 配置(早期)

你需要创建一个或多个 XML 文件,在里面手动定义每一个 Bean,并配置它们的依赖关系。

xml 复制代码
<!-- applicationContext.xml -->
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
                           http://www.springframework.org/schema/beans/spring-beans.xsd
                           http://www.springframework.org/schema/context
                           http://www.springframework.org/schema/context/spring-context.xsd">

    <!-- 1. 必须手动开启注解扫描 -->
    <context:component-scan base-package="com.example.myapp"/>

    <!-- 2. 手动配置一个数据源 Bean -->
    <bean id="dataSource" class="org.apache.commons.dbcp2.BasicDataSource">
        <property name="driverClassName" value="com.mysql.cj.jdbc.Driver"/>
        <property name="url" value="jdbc:mysql://localhost:3306/mydb"/>
        <property name="username" value="root"/>
        <property name="password" value="password"/>
    </bean>

    <!-- 3. 手动配置 JdbcTemplate,并注入 dataSource -->
    <bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
        <constructor-arg ref="dataSource"/>
    </bean>
    
    <!-- 还有更多... TransactionManager, ViewResolver... -->
</beans>
b. Java 配置(后期,有所改进)

后来 Java 配置(@Configuration)取代了大部分 XML,但你仍然需要手动配置很多东西。

java 复制代码
@Configuration
@ComponentScan("com.example.myapp") // 1. 仍然需要手动指定扫描路径
public class AppConfig {

    // 2. 仍然需要手动创建 DataSource Bean
    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource dataSource = new DriverManagerDataSource();
        dataSource.setDriverClassName("com.mysql.cj.jdbc.Driver");
        dataSource.setUrl("jdbc:mysql://localhost:3306/mydb");
        dataSource.setUsername("root");
        dataSource.setPassword("password");
        return dataSource;
    }
    
    // ... 其他 Bean 的配置
}
c. 手动启动容器

你还需要一个 main 方法来手动加载配置,并启动 Spring IoC 容器。

java 复制代码
public class Main {
    public static void main(String[] args) {
        // 手动创建和启动 IoC 容器
        ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
        
        // 从容器中获取 Bean
        MyService myService = context.getBean(MyService.class);
        myService.doWork();
    }
}

痛点总结:

  1. 配置繁琐:大量的 Bean(如数据源、事务管理器、视图解析器)需要你像搭积木一样手动配置。
  2. 需要明确指定扫描路径@ComponentScan<context:component-scan> 必须明确告诉 Spring 去哪里找你的 Bean。
  3. 依赖管理复杂 :你需要手动管理一大堆 spring-core, spring-web, spring-webmvc 等 jar 包,并确保它们的版本相互兼容,这简直是噩梦。
  4. 需要手动启动:启动容器的代码是样板化的,但每个项目都得写一遍。

2. 有了 Spring Boot 之后

Spring Boot 通过两大神器,彻底改变了这一切:Starters(启动器)Auto-Configuration(自动配置)

a. @SpringBootApplication:一个顶三个

你只需要在主类上加一个注解:

java 复制代码
@SpringBootApplication
public class MyApplication {
    public static void main(String[] args) {
        // 一行代码启动,所有事情都自动完成了
        SpringApplication.run(MyApplication.class, args);
    }
}

这个 @SpringBootApplication 注解其实是一个组合注解,它默认包含了:

  • @Configuration: 表明这是一个 Java 配置类。
  • @EnableAutoConfiguration : 这是 Spring Boot 的核心魔法! 它会告诉 Spring Boot 根据你 classpath(类路径)上的 jar 包,来"猜测"你可能需要什么样的配置,并自动帮你完成。
  • @ComponentScan : 自动扫描 主类所在的包及其所有子包下的组件(@Component, @Service 等),你再也不用指定 base-package 了。
b. Starters:简化依赖管理

你不再需要逐个添加 Spring 的 jar 包。想用 Web 功能?只需要一个依赖:

xml 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

这个 starter 会自动帮你引入所有相关的、且版本兼容的依赖(Spring MVC, Tomcat, Jackson 等)。想用数据库?加入 spring-boot-starter-data-jpa 即可。

c. Auto-Configuration:智能的 Bean 配置

这是对 IoC 配置的最大简化。自动配置的工作原理是:

  1. 侦测 Classpath:Spring Boot 检查你的项目中引入了哪些 Starters 和库。
  2. 条件化配置 :它内部有大量的 @ConditionalOnClass, @ConditionalOnBean 等条件注解。
    • 例如 :当它发现你的 classpath 中有 tomcat-embedded.jar 时(由 starter-web 引入),它就自动为你配置好一个嵌入式的 Tomcat 服务器 Bean。
    • 又例如 :当它发现 classpath 中有 DataSource.class 并且你没有 手动配置一个 DataSource Bean 时,它就会尝试读取 application.properties 文件中的 spring.datasource.* 属性,并自动 为你创建一个 DataSource Bean。

所以,之前你需要手动配置的 DataSource,现在只需要在 application.properties 中提供几个属性就行了:

properties 复制代码
spring.datasource.url=jdbc:mysql://localhost:3306/mydb
spring.datasource.username=root
spring.datasource.password=password

Spring Boot 会在幕后为你完成 @Bean 的创建和配置工作。

总结

特性 纯 Spring 框架 Spring Boot 如何简化
组件扫描 需手动配置 <context:component-scan>@ComponentScan(basePackages=...) @SpringBootApplication 默认扫描主类及其子包,无需配置。
依赖管理 需手动添加多个 jar 包并处理版本冲突。 提供 Starters,只需一个依赖即可引入一套功能和兼容的版本。
通用 Bean 配置 需手动配置 DataSource, TransactionManager, DispatcherServlet 等大量样板 Bean。 通过 Auto-Configuration,根据 classpath 自动配置绝大多数通用 Bean。
外部配置 需手动配置 PropertySourcesPlaceholderConfigurer 来读取 .properties 文件。 默认支持 application.properties/.yml,直接通过 @Value@ConfigurationProperties 即可注入。
应用启动 需手动编写 main 方法来创建和启动 ApplicationContext 提供 SpringApplication.run() 一行代码即可启动,内嵌 Web 服务器。

总而言之,Spring Boot 并没有改变 IoC 的核心,而是为 IoC 容器穿上了一件极其智能的"自动化装甲"。它将业界沉淀下来的实践固化为"约定"和"自动配置",让开发者从繁琐的配置工作中彻底解放,真正做到"开箱即用",让开发者专注于业务逻辑的实现。