老师总结的Bean生命周期

本文详细解析了Spring框架中Bean从创建到销毁的完整生命周期,包括实例化、依赖注入、初始化及销毁等关键阶段,深入探讨各阶段触发的接口回调与方法执行顺序。

>>>>Bean的生命周期

1.首先容器启动后,会对scope为singleton且非懒加载的bean进行实例化,

 

2.按照Bean定义信息配置信息,注入所有的属性,

 

3.如果Bean实现了BeanNameAware接口,会回调该接口的setBeanName()方法,传入该Bean的id,此时该Bean就获得了自己在配置文件中的id,

 

4.如果Bean实现了BeanFactoryAware接口,会回调该接口的setBeanFactory()方法,传入该Bean的BeanFactory,这样该Bean就获得了自己所在的BeanFactory,

 

5.如果Bean实现了ApplicationContextAware接口,会回调该接口的setApplicationContext()方法,传入该Bean的ApplicationContext,这样该Bean就获得了自己所在的ApplicationContext,

 

6.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessBeforeInitialzation()方法,

 

7.如果Bean实现了InitializingBean接口,则会回调该接口的afterPropertiesSet()方法,

 

8.如果Bean配置了init-method方法,则会执行init-method配置的方法,

 

9.如果有Bean实现了BeanPostProcessor接口,则会回调该接口的postProcessAfterInitialization()方法,

 

10.经过流程9之后,就可以正式使用该Bean了,对于scope为singleton的Bean,Spring的ioc容器中会缓存一份该bean的实例,而对于scope为prototype的Bean,每次被调用都会new一个新的对象,期生命周期就交给调用方管理了,不再是Spring容器进行管理了

 

11.容器关闭后,如果Bean实现了DisposableBean接口,则会回调该接口的destroy()方法,

 

12.如果Bean配置了destroy-method方法,则会执行destroy-method配置的方法,至此,整个Bean的生命周期结束

 

内容概要:本详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于转型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
<think>我们正在讨论Spring Bean生命周期,特别是构造函数、属性赋值和初始化方法的执行顺序。 根据提供的引用,我们可以总结如下: 1. 引用[1]提到属性赋值可以通过@Value、@Autowired等注解完成。 2. 引用[2]和[3]提到了init-method和destroy-method,以及使用注解@PostConstruct和@PreDestroy。 3. 引用[4]和[5]则提供了关于构造函数、afterPropertiesSet和init-method执行顺序的信息。 具体执行顺序为: 1. 首先调用构造函数来实例化Bean。 2. 然后进行属性赋值(例如通过setter方法或字段注入,使用@Autowired、@Resource等)。 3. 如果Bean实现了InitializingBean接口,则调用afterPropertiesSet()方法。 4. 接着调用自定义的初始化方法(通过@PostConstruct注解的方法或通过init-method指定的方法)。 注意:@PostConstruct注解的方法会在afterPropertiesSet()方法之前执行吗?实际上,根据Spring官方档: - @PostConstruct注解的方法会在依赖注入(即属性赋值)完成后被调用,并且在InitializingBean的afterPropertiesSet()方法之前以及init-method之前执行。 因此,更详细的顺序应该是: 1. 构造函数 2. 属性赋值(依赖注入) 3. @PostConstruct 注解的方法 4. InitializingBean的afterPropertiesSet()方法 5. 自定义的init-method方法 引用[4]中的例子是一个通过XML配置bean,它有一个构造器参数和一个init-method。在这个例子中,构造器先执行(传入参数),然后执行init-method。 引用[5]则说明了在构造函数中直接使用依赖注入的属性可能会出现问题,因为此时属性还没有被注入(即构造函数执行时,依赖注入还没有发生)。 所以,总结执行顺序为: 1. 构造函数(此时依赖还未注入,所以构造函数中不能使用依赖的属性) 2. 依赖注入(属性赋值) 3. 初始化回调(按顺序): a. 使用@PostConstruct注解的方法 b. 实现了InitializingBean接口的afterPropertiesSet()方法 c. 自定义的init-method(通过XML或@Bean(initMethod="...")指定) 验证:我们可以通过一个简单的例子来验证这个顺序。 例如,定义一个Bean: ```java public class ExampleBean implements InitializingBean { private String name; public ExampleBean() { System.out.println("1. 构造函数"); } public void setName(String name) { this.name = name; System.out.println("2. 属性赋值"); } @PostConstruct public void postConstruct() { System.out.println("3. @PostConstruct方法"); } @Override public void afterPropertiesSet() throws Exception { System.out.println("4. InitializingBean的afterPropertiesSet"); } public void initMethod() { System.out.println("5. 自定义的init-method"); } } ``` 在XML配置中: ```xml <bean id="exampleBean" class="ExampleBean" init-method="initMethod"> <property name="name" value="Spring"/> </bean> ``` 或者使用Java配置: ```java @Bean(initMethod = "initMethod") public ExampleBean exampleBean() { ExampleBean exampleBean = new ExampleBean(); exampleBean.setName("Spring"); return exampleBean; } ``` 输出顺序应该是: 1. 构造函数 2. 属性赋值 3. @PostConstruct方法 4. afterPropertiesSet 5. 自定义的init-method 因此,回答用户的问题:在Spring中,Bean的创建过程首先是调用构造函数,然后进行属性赋值(依赖注入),接着依次执行@PostConstruct注解的方法、InitializingBean接口的afterPropertiesSet方法,最后执行自定义的init-method方法。 注意:如果同时存在多种初始化方法,那么它们的执行顺序就是上面列出的顺序。 另外,关于销毁方法的顺序(与问题无关,但作为补充): 1. @PreDestroy注解的方法 2. DisposableBean接口的destroy()方法 3. 自定义的destroy-method方法 引用[3]中也提到了这些销毁方法。 所以,最终回答如下: </think>在Spring中,Bean的构造函数、属性赋值与初始化方法执行顺序遵循严格的生命周期规范,具体顺序如下: ### 执行顺序详解 1. **构造函数调用**(实例化) Spring首先调用Bean的构造函数创建对象实例。 **注意**:此时依赖注入尚未完成,构造函数内无法使用注入的属性(否则会抛`NullPointerException`)[^5]。 2. **属性赋值**(依赖注入) - 通过Setter方法(如`<property>`标签) - 或字段注入(如`@Autowired`、`@Resource`、`@Value`) 完成所有依赖项的注入[^1][^3]。 3. **初始化方法执行**(按顺序): a. **`@PostConstruct`注解方法** b. **`InitializingBean.afterPropertiesSet()`**(实现接口) c. **自定义`init-method`**(XML中`init-method`属性或`@Bean(initMethod)`)[^2][^3][^4] ### 顺序验证示例 ```java public class DemoBean implements InitializingBean { // 1. 构造函数先执行 public DemoBean() { System.out.println("构造函数执行"); } // 2. 属性注入(Setter或字段注入) @Autowired private Dependency dep; // 3a. 最先执行的初始化方法 @PostConstruct public void postConstruct() { System.out.println("@PostConstruct方法执行"); } // 3b. 接着执行接口方法 @Override public void afterPropertiesSet() { System.out.println("afterPropertiesSet()执行"); } // 3c. 最后执行自定义init-method public void customInit() { System.out.println("init-method方法执行"); } } ``` **输出顺序**: ``` 构造函数执行 @PostConstruct方法执行 afterPropertiesSet()执行 init-method方法执行 ``` ### 关键规则 1. **属性必须在构造函数之后注入**:构造函数中无法使用未初始化的依赖[^5]。 2. **初始化方法依赖注入结果**:所有初始化方法(`@PostConstruct`、`afterPropertiesSet()`、`init-method`)均可安全使用注入的属性[^3][^4]。 3. **销毁顺序**(补充): `@PreDestroy` → `DisposableBean.destroy()` → 自定义`destroy-method`[^3]。 > 此顺序由Spring IoC容器严格保证,确保依赖可用性和生命周期可控性[^1][^3][^4]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值