首先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,并配置它们的依赖关系。
<!-- 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/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://www.springframework.org/schema/contexthttp://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,但你仍然需要手动配置很多东西。
@Configuration
@ComponentScan("com.example.myapp") // 1. 仍然需要手动指定扫描路径
public class AppConfig {// 2. 仍然需要手动创建 DataSource Bean@Beanpublic 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 容器。
public class Main {public static void main(String[] args) {// 手动创建和启动 IoC 容器ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);// 从容器中获取 BeanMyService myService = context.getBean(MyService.class);myService.doWork();}
}
痛点总结:
- 配置繁琐:大量的 Bean(如数据源、事务管理器、视图解析器)需要你像搭积木一样手动配置。
- 需要明确指定扫描路径:
@ComponentScan
或<context:component-scan>
必须明确告诉 Spring 去哪里找你的 Bean。 - 依赖管理复杂:你需要手动管理一大堆
spring-core
,spring-web
,spring-webmvc
等 jar 包,并确保它们的版本相互兼容,这简直是噩梦。 - 需要手动启动:启动容器的代码是样板化的,但每个项目都得写一遍。
2. 有了 Spring Boot 之后
Spring Boot 通过两大神器,彻底改变了这一切:Starters(启动器) 和 Auto-Configuration(自动配置)。
a. @SpringBootApplication
:一个顶三个
你只需要在主类上加一个注解:
@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 功能?只需要一个依赖:
<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 配置的最大简化。自动配置的工作原理是:
- 侦测 Classpath:Spring Boot 检查你的项目中引入了哪些 Starters 和库。
- 条件化配置:它内部有大量的
@ConditionalOnClass
,@ConditionalOnBean
等条件注解。- 例如:当它发现你的 classpath 中有
tomcat-embedded.jar
时(由starter-web
引入),它就自动为你配置好一个嵌入式的 Tomcat 服务器 Bean。 - 又例如:当它发现 classpath 中有
DataSource.class
并且你没有手动配置一个DataSource
Bean 时,它就会尝试读取application.properties
文件中的spring.datasource.*
属性,并自动为你创建一个DataSource
Bean。
- 例如:当它发现你的 classpath 中有
所以,之前你需要手动配置的 DataSource
,现在只需要在 application.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 容器穿上了一件极其智能的“自动化装甲”。它将业界沉淀下来的实践固化为“约定”和“自动配置”,让开发者从繁琐的配置工作中彻底解放,真正做到“开箱即用”,让开发者专注于业务逻辑的实现。