当前位置: 首页 > 后端技术 > Java

SpringBean生命周期源码精析

时间:2023-04-02 09:57:34 Java

概述生命周期大致分为四步。当然,源码作者并没有说的那么清楚,主要是为了方便理解。创建bean的主要流程代码在org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBeanInstance.doCreateBean实例化准备实例化属性注入初始化实例化准备对于普通的java对象,创建一个对象只需要四步就可以编译一个java文件和生成.class文件Receiveneworreflecttocreateanobject信号通过类加载器将class文件加载到JVM虚拟机中,初始化对象可供使用。与Bean对象不同的是,Bean可以通过xml定义,也可以通过注解(@Component、@Configuration等)来定义。SpringBoot启动时,根据@ComponentScan的作用域进行扫描,将定义封装成一个BeanDefinition实例,其中包含了很多定义的元数据,如@Scope、@Lazy等,最后将收集到的BeanDefinition放入beanDefinitionMap中,键是beanName,值是一个BeanDefinition对象。万恶之源:org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean1。通过beannamefinalRootBeanDefinitionmbd=getMergedLocalBeanDefinition(beanName);获得BeanDefinition;2。调用BeanPostProcessors处理bean元信息(一般不要使用try{//让BeanPostProcessors有机会返回一个代理而不是目标bean实例。Objectbean=resolveBeforeInstantiation(beanName,mbdToUse);if(bean!=null){returnbean;}}3.调用org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean创建beantry{ObjectbeanInstance=doCreateBean(beanName,mbdToUse,args);if(logger.isTraceEnabled()){logger.trace("Finishedcreatinginstanceofbean'"+beanName+"'");}returnbeanInstance;}从而进入doCreateBean进行实例化Instantiation1.SpringBoot首先查询缓存,如果缓存中没有实例化的bean。实例化的代码如下createBeanInstance(beanName,mbd,args);}finalObjectbean=instanceWrapper.getWrappedInstance();ClassbeanType=instanceWrapper.getWrappedClass();if(beanType!=NullBean.class){mbd.resolvedTargetType=beanType;}2.实例完成后,BeanPostProcessor进行后处理,就是把符合条件的属性和方法找出来,封装起来,以便后面填充属性时直接使用。#applyMergedBeanDefinitionPostProcessors//允许后处理器修改合并的bean定义。synchronized(mbd.postProcessingLock){if(!mbd.postProcessed){}catch(Throwableex){thrownewBeanCreationException(mbd.getResourceDescription(),beanName,“合并bean定义后处理失败”,ex);}mbd.postProcessed=true;}}3.将这个bean加入到三级文件夹中。#addSingletonFactory//急切地缓存单例,以便能够解析循环引用//即使被BeanFactoryAware.booleanearlySingletonExposure之类的生命周期接口触发时也是如此if(logger.isTraceEnabled()){logger.trace("急切地缓存bean'"+beanName+"'以允许解析潜在的循环引用");}addSingletonFactory(beanName,()->getEarlyBeanReference(beanName,mbd,bean));}属性注册代码如下#populateBean//初始化beaninstance.ObjectexposedObject=bean;try{populateBean(beanName,mbd,instanceWrapper);exposedObject=initializeBean(beanName,exposedObject,mbd);}catch(Throwableex){if(exinstanceofBeanCreationException&&beanName.equals(((BeanCreationException)ex).getBeanName())){throw(BeanCreationException)ex;}else{thrownewBeanCreationException(mbd.getResourceDescription(),beanName,“bean初始化失败”,ex);}}注意到属性注册后,有这么一段代码if(earlySingletonExposure){ObjectearlySingletonReference=getSingleton(beanName,false);if(earlySingletonReference!=null){if(exposedObject==bean){exposedObject=earlySingletonReference;}elseif(!this.allowRawInjectionDespiteWrapping&&hasDependentBean(beanName)){String[]dependentBeans=getDependentBeans(beanName);SetactualDependentBeans=newLinkedHashSet<>(dependentBeans.length);for(StringdependentBean:dependentBeans){if(!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)){actualDependentBeans.add(dependentBean);}}if(!actualDependentBeans.isEmpty()){thrownewBeanCurrentlyInCreationException(beanName,"Beanwithname'"+beanName+"'hasbeeninjectedintootherbeans["+StringUtils.collectionToCommaDelimitedString(actualDependentBeans)+"]在其原始版本作为循环引用的一部分,但最终被“+”包装。这意味着其他bean不使用“+”bean的最终版本。这通常是过度急切的类型匹配的结果-考虑使用"+"'getBeanNamesOfType'关闭了'allowEagerInit'标志,例如。");}}}}这段代码是判断bean在缓存中的地址是否与自己创建的bean相同。如果不同,则继续判断!this.allowRawInjectionDespiteWrapping&&hasDependentBean(beanName),如果为true,则会抛出异常。在这个过程中,可以设置很多Hooks。查看Aware接口BeanPostProcessorInitializingBean接口自定义init-methodBeanPostProcessorAware接口Aware接口也称为感知接口,实现该接口的类可以通过BeanNameAware获取容器中bean的名称BeanFactoryAware获取当前beanFactory,然后调用容器服务ApplicationContextAware获取当前应用上下文调用容器服务MessageSourceAware获取消息源获取文本信息ApplicationEventPublisherAware应用事件发布者,用于发布事件ResourceLoaderAware获取资源加载器,可以获取外部资源文件@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println("postProcessBeforeInitialization..."+beanName+"=>"+bean);返回豆;}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println("postProcessAfterInitialization..."+beanName+"=>"+bean);返回豆;}}其他源码解析顺序:Aware接口--预处理接口--初始化Bean接口--自定义初始化方法接口--后处理接口Bean:前置后接口代码演示publicclassBeanInitimplementsBeanNameAware,BeanPostProcessor,InitializingBean{publicStringbeanName;publicvoidinit(){System.out.println("自定义初始化方法");}publicvoiddestroy(){System.out.println("自定义销毁方法");}@OverridepublicvoidafterPropertiesSet()throwsException{System.out.println(beanName+"InitializingBean");}@OverridepublicObjectpostProcessBeforeInitialization(Objectbean,StringbeanName)throwsBeansException{System.out.println(beanName+"postProcessBeforeInitialization");返回BeanPostProcessor.super.postProcessBeforeInitialization(bean,beanName);}@OverridepublicObjectpostProcessAfterInitialization(Objectbean,StringbeanName)throwsSystem.printlBeansExceanption{e+"初始化后处理");返回BeanPostProcessor.super.postProcessAfterInitialization(bean,beanName);}@OverridepublicvoidsetBeanName(Strings){this.beanName=s;}}@SpringBootApplication(exclude={DataSourceAutoConfiguration.class})//启动类publicclassDemoApplication{publicstaticvoidmain(String[]args){SpringApplication.run(DemoApplication.class,args);}@Bean(initMethod="init",destroyMethod="destroy")publicBeanInitsetInitTest(){returnnewBeanInit();}}org.springframework.context.support.AbstractApplicationContext#refresh(入口)org.springframework.context.support.AbstractApplicationContext#finishBeanFactoryInitialization(初始化单例对象入口)org.springframework.beans.factory.config.ConfigurableListableBeanFactory#preInstantiate单列(例如对象入口)org.springframework.beans.factory.support.AbstractBeanFactory#getBean(java.lang.String)(万恶之源,获取并创建Bean入口)org.springframework.beans.factory.support.AbstractBeanFactory#doGetBean(实际获取并创建Bean的实现)org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#getSingleton(java.lang.String)(尝试从缓存中获取)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String,org.springframework.beans.factory.support.RootBeanDefinition,java.lang.Object[])(实例化Bean)org.实例化Bean到三级缓存)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean(实例化属性注入)org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.郎。字符串,Java。郎。对象,组织。春天framework.beans.factory.support.RootBeanDefinition)(初始化入口)参考文章如何理解springbean的生命周期,实际应用场景?Spring源码分析——八、applyMergedBeanDefinitionPostProcessors源码分析

最新推荐
猜你喜欢