Appearance
Spring Framework 核心基础
很多人一提 Spring,第一反应是注解、Controller、自动配置。
但如果继续往下看 Spring Framework 本身到底在管什么,更实在一点,它在给 Java 企业应用提供一层稳定的容器、配置、事件、资源、调度和整合底座。
如果这层底座没理顺,后面再看 Spring MVC、Spring Boot、@Transactional、@Scheduled,就很容易只记住“会用”,却不知道它们为什么能工作。
这篇主要看:
Spring Framework到底是什么- 它不是一个单模块框架,而是一组基础模块
BeanFactory和ApplicationContext是什么关系spring-context这层到底补了哪些关键能力- 为什么
@Scheduled本质上属于Spring Framework
1. Spring Framework 到底是什么
Spring Framework 可以看成 Spring 生态的基础框架底座。
它主要解决的是:
- 对象怎么交给容器统一管理
- 对象之间的依赖怎么组织
- 配置、资源、环境变量怎么统一读取
- 事件、事务、调度这类通用能力怎么接进应用
- 各种技术栈怎么在统一模型下整合
所以它不是某一个注解库,也不是单独一个 Web 框架,而是一整层企业开发基础设施。
🌟 先记这一句就够了:Spring Framework 管的是应用底座,不只是接口开发。
2. 为什么它不是一个单模块框架
很多人第一次学 Spring,容易把它理解成“一个大框架”。
它其实是由多组基础模块一起拼出来的。
其中最值得优先建立认知的几层通常是:
| 模块 | 主要负责什么 |
|---|---|
spring-core | 最基础的工具能力、类型转换、资源抽象等底层支持 |
spring-beans | Bean 定义、Bean 创建、依赖注入这条主线 |
spring-context | 在 Bean 容器之上补齐更完整的应用上下文能力 |
spring-aop | AOP、代理、横切逻辑抽离 |
spring-tx | 统一事务抽象与事务管理 |
spring-expression | SpEL 表达式能力 |
如果从学习路径看,可以把它们压成一条更容易记的线:
core负责基础支撑beans负责 Bean 容器context把 Bean 容器升级成更完整的应用上下文aop、tx在这个基础上继续补横切能力
这里最容易被忽略,但又最关键的一层,就是 spring-context。
3. Spring Framework 和 Spring MVC、Spring Boot 是什么关系
这部分一定要先理顺。
3.1 和 Spring MVC 的关系
Spring MVC 是 Spring 体系里的 Web 层框架。
它主要解决的是:
- HTTP 请求如何进入应用
- Controller 如何匹配
- 参数如何绑定
- 响应如何返回
而这些能力,建立在更基础的 Spring 容器和配置体系之上。
所以更自然的理解是:Spring MVC 是 Spring Framework 之上的 Web 层能力,不等于整个 Spring Framework。
3.2 和 Spring Boot 的关系
Spring Boot 也不是替代 Spring Framework。
它更像是:站在 Spring Framework 之上,把项目启动、自动配置、依赖选择和工程组织进一步简化。
所以记成:
Spring Framework是底座Spring MVC是 Web 层能力Spring Boot是工程化简化体系
4. BeanFactory 和 ApplicationContext 是什么关系
这两个概念如果不先区分清楚,后面很多内容都会混。
4.1 BeanFactory
BeanFactory 是更原始的 Bean 容器抽象。
它的主线比较纯粹:
- 管理 Bean 定义
- 创建 Bean
- 根据名称或类型获取 Bean
可以把它理解成:把“对象交给容器管理”这件事做起来。
4.2 ApplicationContext
ApplicationContext 是在 BeanFactory 基础上扩展出来的更完整应用上下文。
它不只是“能拿到 Bean”,还补了很多企业项目里真正常用的能力。
| 能力 | 作用 |
|---|---|
| 事件机制 | 支持发布事件、监听事件 |
| 资源加载 | 统一读取 classpath:、文件系统、URL 等资源 |
| 环境抽象 | 统一读取配置项、环境变量、Profile |
| 国际化支持 | 统一消息与多语言资源 |
| 应用集成入口 | 更自然地接入调度、校验、AOP、事务等能力 |
🌟 所以真实项目里,我们更常接触的通常不是 BeanFactory,而是 ApplicationContext。
5. 为什么 ApplicationContext 是日常开发里的主入口
很多 Spring 能力真正串起来,靠的不是“能不能 getBean()”,而是应用上下文这一层。
5.1 资源加载
企业应用里,经常要读取:
- 配置文件
- 模板文件
- 脚本资源
- 远程或本地资源
ApplicationContext 通过 Resource 抽象,把这些读取入口统一起来。
它解决的是:不要让应用到处自己判断 classpath、文件路径和 URL。
5.2 环境与配置
项目一旦区分开发、测试、生产环境,就一定会碰到:
- 配置项读取
- 环境变量覆盖
- Profile 切换
这条线主要由 Environment 抽象承担。
它解决的是:配置不应该散落在代码里硬编码,而应该统一交给环境模型管理。
5.3 事件机制
事件机制不是“高级玩法”,很多企业项目都会用到:
- 下单成功后触发通知
- 用户注册后触发欢迎消息
- 某个状态变化后触发后续处理
它解决的是:一个动作发生后,后续逻辑不一定都要硬塞在同一个业务方法里。
5.4 调度能力
很多人以为定时任务是 Spring Boot 提供的。
更接近真实归属的是:调度能力的底层属于 Spring Framework,尤其是 spring-context 这一层里的 scheduling 支持。
也就是说,@Scheduled 的能力归属在 Framework 这条线上,只是我们平时更常在 Boot 项目里使用它。
6. 一个最小的 ApplicationContext 能力示例
下面这个例子不追求完整项目结构,只是帮助理解 ApplicationContext 为什么不只是“拿 Bean”。
java
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.event.EventListener;
import org.springframework.core.io.Resource;
/**
* 演示 ApplicationContext 常见能力:
* 1. 获取 Bean
* 2. 读取环境配置
* 3. 加载资源
* 4. 发布事件
*/
public class ApplicationContextDemo {
public static void main(String[] args) throws Exception {
try (AnnotationConfigApplicationContext context =
new AnnotationConfigApplicationContext(AppConfig.class)) {
MailService mailService = context.getBean(MailService.class);
mailService.send("user@example.com", "welcome");
String activeProfile = context.getEnvironment()
.getProperty("spring.profiles.active", "dev");
System.out.println("activeProfile = " + activeProfile);
Resource resource = context.getResource("classpath:application.properties");
System.out.println("config exists = " + resource.exists());
context.publishEvent(new OrderCreatedEvent("ORD-1001"));
}
}
/**
* 下单事件。
*/
public record OrderCreatedEvent(String orderNo) {
}
/**
* Java 配置类。
*/
@Configuration
static class AppConfig {
@Bean
public MailService mailService() {
return new MailService();
}
@Bean
public OrderCreatedListener orderCreatedListener() {
return new OrderCreatedListener();
}
}
/**
* 邮件服务示例。
*/
static class MailService {
public void send(String to, String message) {
System.out.println("send mail to " + to + ": " + message);
}
}
/**
* 订单事件监听器。
*/
static class OrderCreatedListener {
@EventListener
public void handle(OrderCreatedEvent event) {
System.out.println("receive order event: " + event.orderNo());
}
}
}这段代码最值得看的不是细节语法,而是它背后的 4 个动作:
- 从容器里拿到 Bean
- 从环境模型里读取配置
- 通过统一资源抽象读取配置文件
- 在容器里发布并监听事件
如果只有 BeanFactory 这一层,很多应用级能力就不会像现在这样自然地串起来。
7. @Scheduled 为什么应该归到 Spring Framework
你在项目里最常见到的写法可能是:
java
@EnableScheduling
@Scheduled(cron = "0 0/5 * * * ?")很多人因此会误以为这是 Spring Boot 提供的。
其实更准确的判断应该是:
@Scheduled的包名是org.springframework.scheduling.annotation- 它属于 Spring 的 scheduling 能力
- 这条能力本质上落在
Spring Framework,更具体地说,主要落在spring-context这条线
Spring Boot 做的更多是:
- 让它更容易接进应用
- 让启动配置更省心
- 让你在 Boot 项目里更自然地使用它
🌟 所以结论应该记成:@Scheduled 属于 Spring Framework,Spring Boot 只是让它更容易落地。
如果你想继续看定时任务本身怎么写、cron 怎么选、线程池怎么配,可以接着看:
8. 学 Spring Framework 最该先抓哪些主线
如果你是从“项目会写,但底层老是混”这个状态往前走,最值得先抓的通常是:
core / beans / context之间的分工BeanFactory和ApplicationContext的层次关系IoC / DI到底如何让对象组织起来AOP和事务为什么都建立在代理与容器之上Resource、Environment、事件、调度这些能力为什么属于 Framework 底座
顺着这条线看,再回头理解 Spring MVC、Spring Boot、@Transactional、@Scheduled,层次会清楚很多。
9. 工程上最常见的几个误区
9.1 误区一:Spring Framework 就是注解集合
不是。
注解只是能力的入口表达。
真正重要的是:
- 容器
- 上下文
- 代理
- 事务抽象
- 事件和调度模型
9.2 误区二:只要会 @Autowired 就算理解 Spring
也不够。
真正要继续往下追问的是:
- Bean 是怎么注册的
- 依赖是怎么解析的
- 容器刷新阶段做了什么
- 为什么有些能力一定要依赖
ApplicationContext
9.3 误区三:@Scheduled 是 Boot 才有的功能
不是。
它只是更常在 Boot 项目里出现,但能力归属仍然属于 Spring Framework。
10. 一句话总结
Spring Framework 的核心价值,是把 Bean 容器、应用上下文、资源与环境抽象、事件机制、调度能力、AOP 和事务这些基础能力组织成一套稳定的 Java 企业应用底座。