摘要:使用传统的java应用中创建bean的过程非常简单,直接new完创建对象即可使用,一旦Bean不再使用,Java自动进行垃圾回收。 相比之下spring框架中bean的生命周期相比之下却要复杂的多,正确的理解Spring bean的生命周期可以让开发更好的利用
使用传统的java应用中创建bean的过程非常简单,直接new完创建对象即可使用,一旦Bean不再使用,Java自动进行垃圾回收。 相比之下spring框架中bean的生命周期相比之下却要复杂的多,正确的理解Spring bean的生命周期可以让开发更好的利用各个扩展点完成bean的各种个性化加载和初始化创建逻辑改造:
Hi,我是sharkChili ,是个不断在硬核技术上作死的技术人,是CSDN的博客专家 ,也是开源项目Java Guide 的维护者之一,熟悉Java 也会一点Go ,偶尔也会在C源码 边缘徘徊。写过很多有意思的技术博客,也还在研究并输出技术的路上,希望我的文章对你有帮助,写代码的SharkChili 。
同时也非常欢迎你star我的开源项目mini-redis:https://github.com/shark-ctrl/mini-redis
对于源码的阅读,大部分答案其实都可以在注释中得到答案,所以对于Spring生命周期,我们完全可以从顶层设计的BeanFactory得到答案:
不难看出在Spring的生命周期中,对应Bean的初始化的核心步骤和顺序为:
实例化bean:这是加载一个bean的首要步骤,将需要创建的bean进行实例化。属性填充:我们日常使用bean基本上都是采用@Autowired的方式将其他bean注入,属性填充时就会将需要被注入的bean填充到当前bean实例。进行各种aware获取容器的特定能力:初始化这一步会执行到上述步骤中的各种Aware进行各种设置操作,例如BeanNameAware设置beanName、BeanFactoryAware设置BeanFactory、ApplicationContextAware将ApplicationContext传入到当前bean中。初始化bean:调用BeanPostProcessor和InitializingBean进行各种初始化工作。正常使用bean。销毁bean:应用上下文被销毁,如果实现了DisposableBean或者自定义销毁方法就会将调用这些方法执行回收逻辑。对此,笔者将其转为一张比较直观的图片让读者对整个流程有一个整体的认识,具体细节笔者会在后续文章中展开:
基于上述生命周期我们给出下面这样一段示例代码,注意这里的AService和BService都是空对象:
@Service("aService")@Slf4jpublic class AService implements BeanNameAware, ApplicationContextAware, InitializingBean, DisposableBean { @Autowired private BService bService; @Override public void setBeanName(String name) { log.info(" setBeanName"); } @Override public void setApplicationContext(ApplicationContext applicationContext) throws BeansException { log.info AService setApplicationContext"); } @Override public void afterPropertiesSet throws Exception { log.info afterPropertiesSet"); } @Override public void destroy throws Exception { log.info destroy"); }}因为PostProcessor无法执行自己的所以笔者额外继承并写了一个PostProcessor:
@Component@Slf4jpublic class MyPostProcessor implements BeanPostProcessor { @Override public Object postProcessBeforeInitialization(Object bean, String beanName) throws BeansException { if ("aService".equals(beanName)) { log.info("-*************** postProcessBeforeInitialization"); } return null; } @Override public Object postProcessAfterInitialization(Object bean, String beanName) throws BeansException { if ("aService".equals(beanName)) { log.info("*************** postProcessAfterInitialization"); } return null; }}从输出结果可以看到bean进行初始化阶段的输出,这一点读者可以结合上图比对了解:
2024-02-19 13:09:52.994 INFO 10184 --- [ main] com.sharkChili.service.AService : setBeanName2024-02-19 13:09:52.994 INFO 10184 --- [ main] com.sharkChili.service.AService : AService setApplicationContext2024-02-19 13:09:52.994 INFO 10184 --- [ main] c.sharkChili.processor.MyPostProcessor : -*************** postProcessBeforeInitialization2024-02-19 13:09:52.994 INFO 10184 --- [ main] com.sharkChili.service.AService : afterPropertiesSet2024-02-19 13:09:52.994 INFO 10184 --- [ main] c.sharkChili.processor.MyPostProcessor : *************** postProcessAfterInitialization我们从框架的顶层设计纵览设计,可以看到Beanfacotry核心实现AbstractAutowireCapableBeanFactory,它继承了各种包含bean注册以及bean工厂管理的行为,使得自身具备一个容器的基本骨架:
我们基于上述的案例代码进行源码走读,首先进行bean实例化时执行AbstractAutowireCapableBeanFactory的createBean方法,其内部会调用createBeanInstance
@Override protected Object createBean(String beanName, RootBeanDefinition mbd, @Nullable Object args) throws BeanCreationException { //...... try { Object beanInstance = doCreateBean(beanName, mbdToUse, args); if (logger.isTraceEnabled) { logger.trace("Finished creating instance of bean '" + beanName + "'"); } return beanInstance; }}//调用createBeanInstance完成bean实例化protected Object doCreateBean(String beanName, RootBeanDefinition mbd, @Nullable Object args) throws BeanCreationException { //...... if (instanceWrapper == null) { instanceWrapper = createBeanInstance(beanName, mbd, args); } //......}代码内部会走到AbstractAutowireCapableBeanFactory的instantiateBean其内部会根据实例化策略完成bean的创建,以笔者当前这个单例bean为例,它会走SimpleInstantiationStrategy即通过反射完成bean创建:
protected BeanWrapper instantiateBean(String beanName, RootBeanDefinition mbd) { try { Object beanInstance; if (System.getSecurityManager != null) { //...... } else { //通过实例化策略进行bean初始化 beanInstance = getInstantiationStrategy.instantiate(mbd, beanName, this); } //...... return bw; } catch (Throwable ex) { //...... } }属性填充AbstractAutowireCapableBeanFactory的doCreateBean完成bean实例化之后的就会调用populateBean进行属性填充:
// Initialize the bean instance. Object exposedObject = bean; try { populateBean(beanName, mbd, instanceWrapper); exposedObject = initializeBean(beanName, exposedObject, mbd); }以我们的bean为例,可以看到AutowiredAnnotationBeanPostProcessor循环获取各种处理器最终会找到AutowiredAnnotationBeanPostProcessor对需要进行注入的bean进行加载并注入:
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) { //...... //AutowiredAnnotationBeanPostProcessor会拿到注入的bean的全路径 for (InstantiationAwareBeanPostProcessor bp : getBeanPostProcessorCache.instantiationAware) { PropertyValues pvsToUse = bp.postProcessProperties(pvs, bw.getWrappedInstance, beanName); //...... } } //...... }对应的AutowiredAnnotationBeanPostProcessor的postProcessProperties逻辑如下,可以看到其本质就是通过扫描带有Autowired注解的bean的字段封装到metadata 中调用metadata.inject完成注入:
@Override public PropertyValues postProcessProperties(PropertyValues pvs, Object bean, String beanName) { //获取带有Autowired注解的字段 InjectionMetadata metadata = findAutowiringMetadata(beanName, bean.getClass, pvs); try { //调用inject完成注入 metadata.inject(bean, beanName, pvs); } //...... return pvs; }初始化bean完成属性填充后,AbstractAutowireCapableBeanFactory的doCreateBean方法会继续调用initializeBean完成后续的初始化工作:
exposedObject = initializeBean(beanName, exposedObject, mbd);对应的核心逻辑就在下方,可以看到该方法会调用invokeAwareMethods和applyBeanPostProcessorsAfterInitialization进行初始化工作:
protected Object initializeBean(String beanName, Object bean, @Nullable RootBeanDefinition mbd) { if (System.getSecurityManager != null) { //...... } else { invokeAwareMethods(beanName, bean); } //...... if (mbd == null || !mbd.isSynthetic) { wrappedBean = applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName); } return wrappedBean; }查看invokeAwareMethods可以看到这个方法会拿到各种Aware进行setBeanName、setBeanClassLoader等初始化工作:
private void invokeAwareMethods(String beanName, Object bean) { if (bean instanceof Aware) { if (bean instanceof BeanNameAware) { ((BeanNameAware) bean).setBeanName(beanName); } if (bean instanceof BeanClassLoaderAware) { ClassLoader bcl = getBeanClassLoader; if (bcl != null) { ((BeanClassLoaderAware) bean).setBeanClassLoader(bcl); } } if (bean instanceof BeanFactoryAware) { ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this); } } }而applyBeanPostProcessorsAfterInitialization则会遍历各种框架自带或者我们自定义继承postProcessAfterInitialization(例如我们上文的MyPostProcessor)完成bean初始化工作:
@Override public Object applyBeanPostProcessorsAfterInitialization(Object existingBean, String beanName) throws BeansException { Object result = existingBean; for (BeanPostProcessor processor : getBeanPostProcessors) { Object current = processor.postProcessAfterInitialization(result, beanName); if (current == null) { return result; } result = current; } return result; }注册销毁钩子最后AbstractAutowireCapableBeanFactory的doCreateBean会注册销毁钩子,等容器销毁时,这个bean就会被回收,自此整个bean完成的创建和初始化流程就介绍完毕了:
registerDisposableBeanIfNecessary(beanName, bean, mbd);顶层抽象AbstractAutowireCapableBeanFactory通过SimpleInstantiationStrategy策略instantiateBean反射创建bean。扫描Autowired注解获取需要注入的bean调用InjectionMetadata的inject方法进行属性填充。AbstractAutowireCapableBeanFactory的initializeBean调用各种Aware接口的实现和processor.postProcessAfterInitialization(result, beanName)的实现完成初始化注册销毁钩子registerDisposableBeanIfNecessary。自此文章结束,希望对你有帮助。
来源:散文随风想一点号