解答面试题——Spring bean的作用域和生命周期

前言

这里我不是教学,只是加入我作为一个面试者,遇到这道题我应该怎么回答,我可能回答的不够好,所以希望能给大家帮助的同时也能得到大家的指点。缺乏从哪方面的回答。

Spring Bean的作用域

spring bean的作用域分为5种,分别是 singleton、prototype、request、session、global-session这五种。

singleton

这个模式是单例的,使用这个模式,IOC容器只创建一个实例,并且每次返回都是这一个实例,这种模式是默认的模式,也是我工作中使用最多的模式。

prototype

prototype是原型模式,是多例的,IOC容器可以创建多个Bean实例,每次返回的都是一个新的实例。并且prototype是在使用时创建的,销毁也不受IOC容器管理,而是GC来管理的。
注意:在工作中我遇到一种情况是service明明是prototype,但是我注入到singleton中的Controller中,却只有一个实例,那是因为,Controller是单例的Controller在初始化时,注入的service,这时service被初始化。为什么只是一个bean实例,是因为Controller只创建了一次。
证明:创建多个Controller都注入service,修改service的值并打印,发现每个Controller中打印出来的值并不一样。

request

request是请求模式,是在同一次请求中,IOC容器会创建一个单例bean,这次请求中返回的bean是同一个bean。
我在工作中是用request实现的缓存,同一次请求的缓存。这样会节省很多重复操作。

session

session是会话模式,在同一个会话中,IOC容器会创建一个单例bean,并且每次都会返回同一个bean。
这里和session类似,我使用它是用在会话级的缓存,我用来存放登陆时的用户权限信息,和角色信息。

global-session

这个模式,是所有的session 共享同一个bean。

具体使用:我使用的是注解@scope注解。

Spring Bean的生命周期

简单概述:Bean的创建------>Bean的初始化-------->Bean的销毁
但实际上是我认为应该这样回答:
一个bean从创建到销毁,如果用Beanfactory来管理的话,那么会经历以下几个步骤:
1.IOC 创建bean定义;
2.IOC 按照bean定义来配置Bean的属性;
3.如果Bean实现了BeanNameAware接口,工厂会调用bean的setBeanName方法,参数是beanID ,使用的是观察者模式。
4.如果Bean实现了BeanFactoryAware接口,工厂会调用bean的setBeanName,参数是工厂本身。
5.如果BeanPostProcessors和bean关联,那么会调用postProcessBeforeInitialization方法。
6.Bean 实现了initializingBean 接口那么会调用afterProPertiesSet()方法。
7.Bean 可以定义自己的 初始化方法,通过配置注解的init-method 属性。或者使用@PostConstruct配置初始化方法。
执行initBean方法。
8.BeanPostProcessors没有和bean关联的话 ,那么就会执行后置方法ProcessaAfterInitialization();
9.bean被使用。
10.销毁-如果Bean实现了DisposableBean接口,那么会执行destroy方法,
11.也可以配置bean的销毁方法,通过配置@Bean的destroy-method,或者使用@PreDestroy注解配置销毁方法。

小编的回答应该也就这么多了。如果有更好的回答,希望评论区评论讨论。

<think>好的,用户想了解Spring Bean生命周期,可能是为了面试或者学习Spring框架。我需要详细解释这个过程,结合提供的引用内容,确保信息准确。 首先,用户给出的引用中提到了BeanDefinition的解析,这是Spring容器启动时的重要步骤。Bean生命周期BeanDefinition开始,需要先说明这一点。然后,实例化、属性填充、初始化、销毁等阶段,每个阶段都有对应的处理,比如Aware接口、BeanPostProcessor等。 引用1提到Bean工厂根据BeanDefinition进行实例化初始化,所以生命周期应该从BeanDefinition解析开始。接下来,引用3中的invokeAwareMethods处理BeanNameAware、BeanClassLoaderAwareBeanFactoryAware接口,这应该在属性填充之后,初始化之前。 初始化阶段包括BeanPostProcessor的beforeafter处理,引用45提到postProcessBeforeInitializationpostProcessAfterInitialization方法,这些应该在InitializingBean的afterPropertiesSet自定义init方法之前之后执行。 销毁阶段涉及DisposableBean的destroy方法自定义的销毁方法,引用2中的InitDestroyAnnotationBeanPostProcessor处理销毁前的回调。 需要将这些步骤按顺序排列,确保每个阶段都涵盖,并引用对应的引用来源。同时,用户可能需要面试知识点,所以要用清晰的结构,分阶段说明,并标注关键扩展点,比如BeanPostProcessorAware接口。 可能的问题包括各个阶段的顺序、扩展点的作用、BeanDefinition的角色等。生成相关问题时要覆盖这些方面,帮助用户深入理解。 最后,检查是否符合系统级指令:使用中文,正确引用,相关问题回答结构清晰。确保LaTeX格式正确,但问题中没有数学公式,所以可能不需要使用。不过用户给的示例中有代码块,所以在回答中如果有代码示例的话需要用正确格式,但当前引用中的代码已经用代码块处理了。</think>### Spring Bean生命周期详解(面试知识点) Spring Bean生命周期Spring框架的核心机制之一,理解其过程对面试实际开发都至关重要。以下是详细的生命周期过程,结合关键扩展点: --- #### **1. BeanDefinition解析** Spring容器启动时,所有配置(XML、注解、@Component扫描等)会被解析为$BeanDefinition$对象,存储Bean的元数据(类名、作用域、属性等)[^1]。 示例配置来源: ```xml <bean id="userService" class="com.example.UserService"/> ``` --- #### **2. 实例化(Instantiation)** 通过反射调用构造方法创建Bean实例。 - **无参构造**:默认方式 - **有参构造**:需配合@Autowired或\<constructor-arg\> --- #### **3. 属性填充(Population)** 注入依赖的属性对象,例如: - 通过@Autowired自动注入 - 通过\<property\>标签手动配置 --- #### **4. Aware接口回调** 若Bean实现了特定Aware接口,Spring会注入相关依赖: ```java // 示例:BeanNameAware public class MyBean implements BeanNameAware { @Override public void setBeanName(String name) { System.out.println("Bean名称:" + name); // 输出Bean的ID } } ``` 支持的Aware接口: - $BeanNameAware$(注入Bean ID) - $BeanFactoryAware$(注入BeanFactory) - $ApplicationContextAware$(注入ApplicationContext)[^3] --- #### **5. BeanPostProcessor前置处理** 调用$BeanPostProcessor.postProcessBeforeInitialization()$,可在此修改Bean实例[^4]。 示例: ```java public class CustomProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) { // 对Bean进行增强(如代理) return bean; } } ``` --- #### **6. 初始化(Initialization)** 分两步执行: 1. **InitializingBean.afterPropertiesSet()** 实现该接口的Bean需定义初始化逻辑。 2. **自定义初始化方法** 通过@PostConstruct注解或XML的`init-method`属性指定。 示例: ```java public class UserService implements InitializingBean { @PostConstruct public void customInit() { System.out.println("自定义初始化"); } @Override public void afterPropertiesSet() { System.out.println("接口初始化"); } } ``` --- #### **7. BeanPostProcessor后置处理** 调用$BeanPostProcessor.postProcessAfterInitialization()$,常用于AOP代理生成[^5]。 --- #### **8. Bean就绪** 此时Bean已进入应用上下文,可被其他对象依赖使用。 --- #### **9. 销毁(Destruction)** 容器关闭时触发: 1. **@PreDestroy注解方法** 2. **DisposableBean.destroy()** 3. **XML配置的`destroy-method`** ```java public class ResourceCleanupBean implements DisposableBean { @Override public void destroy() { System.out.println("释放资源"); } } ``` 销毁前会调用$InitDestroyAnnotationBeanPostProcessor$处理回调[^2]。 --- ### **生命周期流程图** $$ \text{BeanDefinition解析} \rightarrow \text{实例化} \rightarrow \text{属性填充} \rightarrow \text{Aware回调} \rightarrow \text{BeanPostProcessor前置} \rightarrow \text{初始化} \rightarrow \text{BeanPostProcessor后置} \rightarrow \text{使用} \rightarrow \text{销毁} $$ --- ### **关键面试点** 1. **BeanPostProcessor的作用**:在初始化前后拦截修改Bean(如AOP代理)。 2. **Aware接口的意义**:让Bean感知容器信息(如Bean ID)。 3. **BeanDefinition的角色**:定义Bean的“蓝图”,决定实例化方式。 ---
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值