引言:在面试中,了解 Spring Bean 的生命周期是非常重要的,因为它直接涉及到了 Spring 框架中对象的创建、初始化、使用和销毁等关键过程。掌握 Spring Bean 的生命周期可以帮助我们更好地理解 Spring 框架的运作机制,以及如何在实际项目中更好地利用 Spring 提供的功能。
题目
面试官:Spring Bean 的生命周期都不会,你走吧下一位
推荐解析
Spring 框架中 Bean 的生命周期
在Spring框架中,Bean的生命周期经历以下几个阶段:
1)实例化: Spring 根据配置文件或注解等方式创建 Bean 实例,并将其存储在容器中。
2)属性赋值: Spring 自动将Bean的属性值从配置文件或注解等方式中注入到 Bean 实例中。
3)初始化: Spring 调用 Bean 实例的 init-method
方法,完成一些初始化的操作,例如建立数据库连接等。
4)使用: Bean 实例已经可以正常使用,供应用程序调用。
5)销毁: Spring 调用 Bean 实例的 destroy-method
方法,完成一些资源的释放和清理操作,例如关闭数据库连接等。
Bean生命周期详解
1)解析类得到 BeanDefinition。
2)如果有多个构造方法,则推断构造方法。
3)确定好构造方法后,进行实例化得到一个对象。
4)对对象中加了 @Autowired
注解的属性进行属性填充。
5)回调 Aware 方法,如 BeanNameAware,BeanFactoryAware。
6)调用 BeanPostProcessor 的初始化前的方法。
7)调用初始化方法。
8)调用 BeanPostProcessor 的初始化后的方法,在这里进行 AOP。
9)如果当前创建的 Bean 是单例的,则会把 Bean 放入单例池里。
10)使用 Bean。
11)Spring 容器关闭时调用 DisposableBean 中的 destroy()
方法。
Bean作用域
Spring 框架提供了以下几种常见的 Bean 作用域:
1)Singleton(单例): Spring 默认的作用域。在 Singleton 作用域下,Spring 容器只会创建 Bean 的一个实例,并在整个应用程序的生命周期内都共享这个实例。
2)Prototype(原型): 每次请求该 Bean 时,Spring 容器都会创建一个新的实例,并返回该实例。即每次调用 getBean()
方法时都会返回一个新的 Bean实例。适用于那些需要状态的 Bean,例如控制器对象、线程安全的对象等。
3)Request(请求): 在 Web 应用中,每个HTTP请求都会创建一个新的 Bean 实例。该作用域仅在 Web 环境中有效,用于在每个 HTTP 请求处理期间创建新的Bean 实例。适用于那些需要在每个请求中保持状态的 Bean。
4)Session(会话): 在 Web 应用中,每个用户会话都会创建一个新的 Bean 实例。该作用域仅在 Web 环境中有效,用于在每个用户会话期间创建新的 Bean 实例。适用于那些需要在整个会话期间保持状态的 Bean。
5)Global Session(全局会话): 该作用域仅在基于 portlet 的 Web 应用中有效。在 portlet 环境中,每个全局会话都会创建一个新的 Bean 实例。
其他补充
鱼聪明 AI 的回答:
在 Spring 框架中,Bean 的生命周期指的是在容器中创建、初始化、使用和销毁 Bean 的整个过程。Spring 容器负责管理 Bean 的生命周期,主要包括以下几个阶段:
- 实例化:容器根据配置信息或者注解创建 Bean 的实例。
- 属性设置:容器将 Bean 的属性值注入到 Bean 实例中,包括通过构造函数注入、属性的注入或者其他特定的注入方式。
- 初始化:在 Bean 实例化并设置好属性之后,Spring 容器可以调用特定的初始化方法进行一些额外的初始化工作。这个初始化方法可以通过 XML 配置文件中的 init-method 属性或者注解中的
@PostConstruct
来指定。 - 使用:此时 Bean 已经完全初始化,可以被应用程序使用了。
- 销毁:当容器关闭时,或者通过编程的方式销毁 Bean 时,容器会调用 Bean 的销毁方法进行资源的释放和清理工作。这个销毁方法可以通过 XML 配置文件中的destroy-method 属性或者注解中的
@PreDestroy
来指定。
强调以下几点:
1)Aware 回调方法: 在 Bean 实例化后,Spring 会调用一些 Aware 接口中的方法,如 BeanNameAware、BeanFactoryAware 等,让 Bean 可以感知到自己的一些环境信息或容器的存在。
2)BeanPostProcessor 的作用: BeanPostProcessor 接口提供了在 Bean 实例化之后和初始化之前以及初始化之后的回调方法,允许开发者在 Bean 初始化的不同阶段进行一些自定义的操作,例如 AOP 功能就是通过 BeanPostProcessor 实现的。
3)DisposableBean 和 InitializingBean 接口: 这两个接口分别定义了在 Bean 销毁前和初始化后的操作方法。通常情况下,建议使用注解方式 (@PostConstruct
和 @PreDestroy
) 来替代这两个接口,因为注解方式更加灵活和方便。
4)Bean 作用域的选择: 在使用 Bean 时,要根据实际需求选择合适的作用域。Singleton 适用于那些无状态的 Bean,Prototype 适用于有状态的 Bean,而 Request 和 Session 则适用于 Web 应用中需要保持状态的 Bean。 Global Session 则适用于特定的 Web 环境。
5)Spring 容器管理 Bean 生命周期的好处: Spring 容器负责管理 Bean 的生命周期,使得开发者可以专注于业务逻辑而不用关心对象的创建、初始化和销毁过程,同时也提供了灵活的扩展机制,可以通过各种扩展点来实现自定义的逻辑。
推荐文章和书籍
文章:https://zhuanlan.zhihu.com/p/86293659
书籍:《 Java 核心技术卷 I 》
欢迎交流
当谈到 Bean 的生命周期时,我们可以探讨以下几个问题:
1)如何确保 Bean 的正确实例化和初始化?
2)Bean 的生命周期中哪些阶段可能存在潜在的安全风险?
3)如何通过配置和编程手段来加强对 Bean 生命周期的管理和监控,以防止潜在的安全漏洞?
这些问题将有助于我们深入了解 Bean 在应用中的运行过程,以及如何在其中加强安全性措施,保障系统的稳定性和安全性。