Spring 的启动流程,90% 的 Java 程序员都说不出来!

开发
本文,我们分析了 Spring启动的流程,通过以下的分析和示例,我们可以看到Spring的启动过程是一个相对复杂但高度自动化的过程。

在开始今天的文章之前,你能先想想 Spring的启动流程吗?

是的...

毫不夸张,很多号称使用 Spring多年的程序员,答不出这个问题。

这篇文章,我们来聊聊 Spring框架的启动过程,本文会逐步拆解 Spring的启动流程,分析其背后的原理,并通过实例来加深理解。最后,还会进行一个小结,帮助大家梳理关键点。

一、Spring启动的整体流程

对于 Spring应用程序的启动过程,我们可以总结成以下 6个主要步骤:

  • 引导阶段:启动器(如Spring Boot的SpringApplication)被调用,初始化应用上下文。
  • 环境准备:加载配置文件,设置环境属性。
  • 创建应用上下文:根据配置创建适当的ApplicationContext(如AnnotationConfigApplicationContext)。
  • 注册Bean定义:扫描包路径,找到并注册所有的Bean定义。
  • 刷新上下文:执行Bean实例化、依赖注入、初始化等步骤。
  • 启动完成:应用程序正式启动,可以接受请求或执行任务。

接下来,我们将逐步深入每一个阶段。

二、关键步骤详解

1. 引导阶段

在Spring Boot项目中,启动通常从一个主类的main方法开始,例如:

@SpringBootApplication
public class DemoApplication {
    public static void main(String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.

这里,SpringApplication.run()方法负责引导整个 Spring应用的启动过程。它的主要作用是创建一个合适的ApplicationContext,准备环境,并刷新上下文以完成初始化。

2. 环境准备

Spring应用启动时,需要加载各种配置,例如application.properties或application.yml文件。这些配置决定了应用的行为和各种参数。

ConfigurableApplicationContext context = new SpringApplicationBuilder(DemoApplication.class)
    .properties("spring.config.name=application")
    .run(args);
  • 1.
  • 2.
  • 3.

在这个阶段,Spring会根据环境(如开发、测试、生产)加载相应的配置,并设置系统属性和环境变量。

3. 创建应用上下文

ApplicationContext是Spring的核心容器,负责管理Bean的生命周期和依赖关系。根据不同的项目需求,Spring可以创建不同类型的上下文,如AnnotationConfigApplicationContext用于基于注解的配置。

AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
context.register(DemoApplication.class);
  • 1.
  • 2.

4. 注册Bean定义

这一步骤涉及到扫描指定的包路径,查找标注了@Component、@Service、@Repository等注解的类,并将它们注册为Bean。

例如:

@Component
public class MyService {
    // ...
}
  • 1.
  • 2.
  • 3.
  • 4.

Spring通过ClassPathBeanDefinitionScanner来扫描这些类,并将它们的定义保存到BeanFactory中,以备后续实例化。

5. 刷新上下文

刷新上下文是整个启动过程的关键,涉及到Bean的实例化、依赖注入、初始化等操作。

主要步骤包括:

  • 实例化Bean:根据Bean定义创建Bean实例。
  • 依赖注入:将需要的依赖自动注入到Bean中。
  • 初始化Bean:执行Bean的初始化方法,如实现InitializingBean接口的afterPropertiesSet()方法,或通过@PostConstruct注解的方法。
  • 处理Bean后置处理器:执行BeanPostProcessor接口的相关方法,允许开发者自定义Bean的处理逻辑。
context.refresh();
  • 1.

6. 启动完成

一旦应用上下文刷新完成,所有的Bean都已经初始化好了,Spring应用就正式启动完成。此时,可以开始接收HTTP请求、执行定时任务等操作。

三、示例演示

下面,我们将通过一个简单的示例来实际看看 Spring是如何启动和管理 Bean的。

假设我们有一个简单的服务类和控制器:

@Component
publicclass GreetingService {
    public String greet() {
        return"Hello, Spring!";
    }
}

@RestController
publicclass GreetingController {
    privatefinal GreetingService greetingService;

    @Autowired
    public GreetingController(GreetingService greetingService) {
        this.greetingService = greetingService;
    }

    @GetMapping("/greet")
    public String greet() {
        return greetingService.greet();
    }
}
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.

在这个例子中:

  • GreetingService被标注为@Component,会被Spring扫描并注册为一个Bean。
  • GreetingController通过构造器注入了GreetingService,这就是依赖注入的体现。

当Spring启动时,它会:

  • 扫描到GreetingService并创建其实例。
  • 创建GreetingController,并将GreetingService的实例注入到控制器中。
  • 完成所有初始化步骤后,应用就可以通过/greet端点返回问候语。

四、总结

本文,我们分析了 Spring启动的流程,通过以上的分析和示例,我们可以看到Spring的启动过程是一个相对复杂但高度自动化的过程。其主要步骤包括引导阶段、环境准备、创建应用上下文、注册 Bean定义、刷新上下文以及最终的启动完成。每一个步骤都涉及到大量的底层机制,例如 Bean的实例化、依赖注入、后置处理器等,这些都是 Spring能够高效管理应用的关键。

责任编辑:赵宁宁 来源: 猿java
相关推荐

2022-02-20 20:12:21

TypeScript

2019-08-22 10:07:33

程序员开发危机

2023-11-07 08:36:34

JavaScriptJS挑战

2021-09-14 07:06:12

程序员拷贝代码

2018-10-15 09:50:07

程序员高薪淘汰

2019-01-23 17:53:05

程序员技能沟通

2017-11-08 10:21:54

iPhone X应用刘海

2016-01-05 09:45:57

设计版式

2016-01-08 11:35:01

移动端设计版面

2020-05-29 10:18:58

python开发代码

2021-11-02 09:54:51

Java开发工具

2021-07-26 09:43:24

代码MapStructs项目

2017-11-14 11:28:49

程序员索引数据

2013-06-17 09:09:31

2018-11-07 15:30:31

程序员工作技术

2019-10-12 09:35:37

程序员人生第一份工作大学

2013-08-20 09:33:59

程序员

2014-07-29 10:30:16

JavaJava程序员

2012-11-08 09:49:30

C++Java程序员

2012-11-02 13:47:31

Java程序员编程
点赞
收藏

51CTO技术栈公众号