Skip to content

Spring Framework 核心基础

很多人一提 Spring,第一反应是注解、Controller、自动配置。

但如果继续往下看 Spring Framework 本身到底在管什么,更实在一点,它在给 Java 企业应用提供一层稳定的容器、配置、事件、资源、调度和整合底座。

如果这层底座没理顺,后面再看 Spring MVCSpring Boot@Transactional@Scheduled,就很容易只记住“会用”,却不知道它们为什么能工作。

这篇主要看:

  1. Spring Framework 到底是什么
  2. 它不是一个单模块框架,而是一组基础模块
  3. BeanFactoryApplicationContext 是什么关系
  4. spring-context 这层到底补了哪些关键能力
  5. 为什么 @Scheduled 本质上属于 Spring Framework

1. Spring Framework 到底是什么

Spring Framework 可以看成 Spring 生态的基础框架底座。

它主要解决的是:

  1. 对象怎么交给容器统一管理
  2. 对象之间的依赖怎么组织
  3. 配置、资源、环境变量怎么统一读取
  4. 事件、事务、调度这类通用能力怎么接进应用
  5. 各种技术栈怎么在统一模型下整合

所以它不是某一个注解库,也不是单独一个 Web 框架,而是一整层企业开发基础设施。

🌟 先记这一句就够了:Spring Framework 管的是应用底座,不只是接口开发。


2. 为什么它不是一个单模块框架

很多人第一次学 Spring,容易把它理解成“一个大框架”。

它其实是由多组基础模块一起拼出来的。

其中最值得优先建立认知的几层通常是:

模块主要负责什么
spring-core最基础的工具能力、类型转换、资源抽象等底层支持
spring-beansBean 定义、Bean 创建、依赖注入这条主线
spring-context在 Bean 容器之上补齐更完整的应用上下文能力
spring-aopAOP、代理、横切逻辑抽离
spring-tx统一事务抽象与事务管理
spring-expressionSpEL 表达式能力

如果从学习路径看,可以把它们压成一条更容易记的线:

  1. core 负责基础支撑
  2. beans 负责 Bean 容器
  3. context 把 Bean 容器升级成更完整的应用上下文
  4. aoptx 在这个基础上继续补横切能力

这里最容易被忽略,但又最关键的一层,就是 spring-context


3. Spring FrameworkSpring MVCSpring Boot 是什么关系

这部分一定要先理顺。

3.1 和 Spring MVC 的关系

Spring MVC 是 Spring 体系里的 Web 层框架。

它主要解决的是:

  1. HTTP 请求如何进入应用
  2. Controller 如何匹配
  3. 参数如何绑定
  4. 响应如何返回

而这些能力,建立在更基础的 Spring 容器和配置体系之上。

所以更自然的理解是:Spring MVC 是 Spring Framework 之上的 Web 层能力,不等于整个 Spring Framework。

3.2 和 Spring Boot 的关系

Spring Boot 也不是替代 Spring Framework

它更像是:站在 Spring Framework 之上,把项目启动、自动配置、依赖选择和工程组织进一步简化。

所以记成:

  1. Spring Framework 是底座
  2. Spring MVC 是 Web 层能力
  3. Spring Boot 是工程化简化体系

4. BeanFactoryApplicationContext 是什么关系

这两个概念如果不先区分清楚,后面很多内容都会混。

4.1 BeanFactory

BeanFactory 是更原始的 Bean 容器抽象。

它的主线比较纯粹:

  1. 管理 Bean 定义
  2. 创建 Bean
  3. 根据名称或类型获取 Bean

可以把它理解成:把“对象交给容器管理”这件事做起来。

4.2 ApplicationContext

ApplicationContext 是在 BeanFactory 基础上扩展出来的更完整应用上下文。

它不只是“能拿到 Bean”,还补了很多企业项目里真正常用的能力。

能力作用
事件机制支持发布事件、监听事件
资源加载统一读取 classpath:、文件系统、URL 等资源
环境抽象统一读取配置项、环境变量、Profile
国际化支持统一消息与多语言资源
应用集成入口更自然地接入调度、校验、AOP、事务等能力

🌟 所以真实项目里,我们更常接触的通常不是 BeanFactory,而是 ApplicationContext


5. 为什么 ApplicationContext 是日常开发里的主入口

很多 Spring 能力真正串起来,靠的不是“能不能 getBean()”,而是应用上下文这一层。

5.1 资源加载

企业应用里,经常要读取:

  1. 配置文件
  2. 模板文件
  3. 脚本资源
  4. 远程或本地资源

ApplicationContext 通过 Resource 抽象,把这些读取入口统一起来。

它解决的是:不要让应用到处自己判断 classpath、文件路径和 URL。

5.2 环境与配置

项目一旦区分开发、测试、生产环境,就一定会碰到:

  1. 配置项读取
  2. 环境变量覆盖
  3. Profile 切换

这条线主要由 Environment 抽象承担。

它解决的是:配置不应该散落在代码里硬编码,而应该统一交给环境模型管理。

5.3 事件机制

事件机制不是“高级玩法”,很多企业项目都会用到:

  1. 下单成功后触发通知
  2. 用户注册后触发欢迎消息
  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 个动作:

  1. 从容器里拿到 Bean
  2. 从环境模型里读取配置
  3. 通过统一资源抽象读取配置文件
  4. 在容器里发布并监听事件

如果只有 BeanFactory 这一层,很多应用级能力就不会像现在这样自然地串起来。


7. @Scheduled 为什么应该归到 Spring Framework

你在项目里最常见到的写法可能是:

java
@EnableScheduling
@Scheduled(cron = "0 0/5 * * * ?")

很多人因此会误以为这是 Spring Boot 提供的。

其实更准确的判断应该是:

  1. @Scheduled 的包名是 org.springframework.scheduling.annotation
  2. 它属于 Spring 的 scheduling 能力
  3. 这条能力本质上落在 Spring Framework,更具体地说,主要落在 spring-context 这条线

Spring Boot 做的更多是:

  1. 让它更容易接进应用
  2. 让启动配置更省心
  3. 让你在 Boot 项目里更自然地使用它

🌟 所以结论应该记成:@Scheduled 属于 Spring Framework,Spring Boot 只是让它更容易落地。

如果你想继续看定时任务本身怎么写、cron 怎么选、线程池怎么配,可以接着看:


8. 学 Spring Framework 最该先抓哪些主线

如果你是从“项目会写,但底层老是混”这个状态往前走,最值得先抓的通常是:

  1. core / beans / context 之间的分工
  2. BeanFactoryApplicationContext 的层次关系
  3. IoC / DI 到底如何让对象组织起来
  4. AOP 和事务为什么都建立在代理与容器之上
  5. ResourceEnvironment、事件、调度这些能力为什么属于 Framework 底座

顺着这条线看,再回头理解 Spring MVCSpring Boot@Transactional@Scheduled,层次会清楚很多。


9. 工程上最常见的几个误区

9.1 误区一:Spring Framework 就是注解集合

不是。

注解只是能力的入口表达。

真正重要的是:

  1. 容器
  2. 上下文
  3. 代理
  4. 事务抽象
  5. 事件和调度模型

9.2 误区二:只要会 @Autowired 就算理解 Spring

也不够。

真正要继续往下追问的是:

  1. Bean 是怎么注册的
  2. 依赖是怎么解析的
  3. 容器刷新阶段做了什么
  4. 为什么有些能力一定要依赖 ApplicationContext

9.3 误区三:@Scheduled 是 Boot 才有的功能

不是。

它只是更常在 Boot 项目里出现,但能力归属仍然属于 Spring Framework


10. 一句话总结

Spring Framework 的核心价值,是把 Bean 容器、应用上下文、资源与环境抽象、事件机制、调度能力、AOP 和事务这些基础能力组织成一套稳定的 Java 企业应用底座。

基于 VitePress 构建的个人技术笔记。