Spring 框架:Bean 生命周期管理
简介
Spring 框架管理 Bean 生命周期的主要目的是确保它们被适当地创建、配置和销毁。Spring Bean 的生命周期分为三个主要阶段:生产、使用和销毁。本文档详细解释了这些阶段,包括过程中涉及的关键步骤、方法和相关的设计模式。
生命周期概述
主要阶段:
- 生产:加载和创建 Bean 定义和实例。
- 使用:在应用程序中管理和使用 Bean 实例。
- 销毁:适当地销毁和清理 Bean 实例。
生命周期主线:
- 启动容器
- 准备容器/环境等
- 生产/使用/销毁 Bean
1. 加载 Bean 定义
加载 Bean 定义是 Spring 容器启动的第一步。这一步骤通过各种方式(如 XML 配置、注解扫描等)将项目中定义的所有 Bean 类找到,并放入
beanDefinitionMap
中。
关键方法调用链:
run()
refreshContext()
refresh()
obtainFreshBeanFactory()
refreshBeanFactory()
loadBeanDefinitions()
代码示例:
// AbstractApplicationContext.java@Overridepublicvoidrefresh()throwsBeansException,IllegalStateException{synchronized(this.startupShutdownMonitor){// 准备容器环境prepareRefresh();// 初始化 BeanFactoryConfigurableListableBeanFactory beanFactory =obtainFreshBeanFactory();// 准备 BeanFactoryprepareBeanFactory(beanFactory);try{// 子类实现后的处理postProcessBeanFactory(beanFactory);// 调用 BeanFactory 后处理器invokeBeanFactoryPostProcessors(beanFactory);// 注册 BeanPostProcessorregisterBeanPostProcessors(beanFactory);// 初始化上下文中的消息源initMessageSource();// 初始化事件机制initApplicationEventMulticaster();// 子类特定的上下文初始化onRefresh();// 检查监听器 bean 并注册到事件机制中registerListeners();// 实例化所有单例 beanfinishBeanFactoryInitialization(beanFactory);// 最后步骤:发布容器刷新事件finishRefresh();}catch(BeansException ex){// 销毁已经创建的单例以避免资源泄露destroyBeans();cancelRefresh(ex);throw ex;}finally{resetCommonCaches();}}}
使用的设计模式:
- 模板方法模式:
refresh()
方法中,定义了处理流程的框架,具体步骤由子类实现。 - 工厂模式:通过
obtainFreshBeanFactory()
方法获取BeanFactory
实例。
2. 创建 Bean 对象
创建 Bean 对象包含四个主要步骤:构造对象、填充属性、初始化实例和注册销毁。
构造对象
通过
createBeanInstance
方法进行构造,先用反射机制从
beanDefinition
中的
beanClass
获取该类的构造方法。选择构造方法的规则如下:
- 如果一个 Bean 只有一个构造方法,只能使用它。
- 如果有多个构造方法,优先选择带有
@Autowired
注解的方法。 - 如果没有带
@Autowired
注解的构造方法,优先选择无参构造方法。 - 如果多个构造方法都有
@Autowired
注解或都是有参的,报错。
代码示例:
// AbstractAutowireCapableBeanFactory.javaprotectedBeanWrappercreateBeanInstance(String beanName,RootBeanDefinition mbd,Object[] args){Class<?> beanClass =resolveBeanClass(mbd, beanName);// 使用构造函数选择器选择合适的构造方法Constructor<?>[] constructors = beanClass.getDeclaredConstructors();Constructor<?> constructorToUse =determineConstructor(mbd, args, constructors);// 通过构造函数创建 Bean 实例returninstantiateBean(beanName, mbd, constructorToUse, args);}privateConstructor<?>determineConstructor(RootBeanDefinition mbd,Object[] args,Constructor<?>[] constructors){// 简化后的逻辑,根据规则选择合适的构造函数for(Constructor<?> constructor : constructors){if(constructor.isAnnotationPresent(Autowired.class)){return constructor;}}// 如果没有找到 @Autowired 注解的构造函数,返回无参构造函数return constructors[0];}
使用的设计模式:
- 工厂模式:通过
instantiateBean()
方法创建 Bean 实例。 - 策略模式:通过不同的策略选择合适的构造函数。
属性填充
通过
populateBean
方法为 Bean 内部的属性进行赋值,通常是通过
@Autowired
注解标注的变量。Spring 会通过三级缓存机制进行依赖注入。
代码示例:
protectedvoidpopulateBean(String beanName,RootBeanDefinition mbd,BeanWrapper bw){PropertyValues pvs = mbd.getPropertyValues();// 依赖注入if(mbd.isAutowireCandidate()){applyPropertyValues(beanName, mbd, bw, pvs);}}
使用的设计模式:
- 依赖注入模式:通过
applyPropertyValues()
方法注入依赖。
初始化实例
- 通过
invokeAwareMethods
方法,为实现了各种Aware
接口的 Bean 注入容器信息(如BeanName
、BeanFactory
等)。 - 通过
invokeInitMethods
方法执行 Bean 的初始化方法,包括实现了InitializingBean
接口的afterPropertiesSet
方法和自定义的initMethod
方法。 - 处理 Bean 的后置处理器(
BeanPostProcessors
),分别在初始化之前和之后进行处理。
代码示例:
protectedObjectinitializeBean(String beanName,Object bean,RootBeanDefinition mbd){// 调用 Aware 接口的方法invokeAwareMethods(beanName, bean);// 调用后置处理器的前置处理方法Object wrappedBean =applyBeanPostProcessorsBeforeInitialization(bean, beanName);// 调用初始化方法invokeInitMethods(beanName, wrappedBean, mbd);// 调用后置处理器的后置处理方法
wrappedBean =applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);return wrappedBean;}
使用的设计模式:
- 装饰模式:通过后置处理器在初始化前后对 Bean 进行装饰。
注册销毁
通过
registerDisposableBean
方法,将实现了
DisposableBean
接口的 Bean 注册,以便在销毁时执行其
destroy
方法。
代码示例:
protectedvoidregisterDisposableBeanIfNecessary(String beanName,Object bean,RootBeanDefinition mbd){if(bean instanceofDisposableBean){registerDisposableBean(beanName,(DisposableBean) bean);}}
使用的设计模式:
- 观察者模式:通过注册销毁方法,确保在容器销毁时正确调用销毁逻辑。
3. 销毁 Bean
销毁 Bean 包括执行销毁前处理器、逐一销毁 Bean 实例和执行自定义销毁方法。
代码示例:
// DisposableBeanAdapter.java@Overridepublicvoiddestroy()throwsException{if(this.invokeDisposableBean){((DisposableBean)this.bean).destroy();}if(this.destroyMethod !=null){this.destroyMethod.invoke(this.bean);}}
使用的设计模式:
- 模板方法模式:定义销毁步骤的框架,具体销毁逻辑由子类实现。
结论
通过上述详细步骤和设计模式,Spring 框架能够有效地管理 Bean 的整个生命周期,从创建、使用到销毁,确保每个阶段都能正确执行。这不仅提高了代码的可读性和可维护性,还增强了应用程序的稳定性和健壮性。
版权归原作者 惊鸿Randy 所有, 如有侵权,请联系我们删除。