游戏电视苹果数码历史美丽
投稿投诉
美丽时装
彩妆资讯
历史明星
乐活安卓
数码常识
驾车健康
苹果问答
网络发型
电视车载
室内电影
游戏科学
音乐整形

Spring源码SpringBean的创建过程(14)

  到目前为止,我们知道Spring创建Bean对象有5中方法,分别是:使用FactoryBean的getObject方法创建使用BeanPostProcessor的子接口InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法创建设置BeanDefinition的Supplier属性进行创建设置BeanDefinition的factorymethod进行创建使用全过程:getBeandoGetBeancreateBeandoCreateBean反射进行创建
  前面4种已经介绍,接下来介绍第5种,我们知道如果使用反射创建,那么必然要知道使用构造函数进行实例化,因为使用构造函数能够将带有参数的设置进去。SmartInstantiationAwareBeanPostProcessor接口
  在前面讲过InstantiationAwareBeanPostProcessor是用来提前实例化对象的,而SmartInstantiationAwareBeanPostProcessor是InstantiationAwareBeanPostProcessor的接口,他是用来干啥呢?
  在createBeanInstance方法中的源码:省略代码。。。。明确构造器从BeanPostProcessor中,对应的是AutowiredAnnotationBeanPostProcessor他是SmartInstantiationAwareBeanPostProcessor的子类,使用determineCandidateConstructors进行解析构造函数Constructorlt;?〔〕ctorsdetermineConstructorsFromBeanPostProcessors(beanClass,beanName);if(ctors!nullmbd。getResolvedAutowireMode()AUTOWIRECONSTRUCTORmbd。hasConstructorArgumentValues()!ObjectUtils。isEmpty(args)){returnautowireConstructor(beanName,mbd,ctors,args);}省略代码。。。。
  点进去:protectedConstructorlt;?〔〕determineConstructorsFromBeanPostProcessors(NullableClasslt;?beanClass,StringbeanName)throwsBeansException{if(beanClass!nullhasInstantiationAwareBeanPostProcessors()){for(BeanPostProcessorbp:getBeanPostProcessors()){if(bpinstanceofSmartInstantiationAwareBeanPostProcessor){SmartInstantiationAwareBeanPostProcessoribp(SmartInstantiationAwareBeanPostProcessor)bp;决定候选的构造函数Constructorlt;?〔〕ctorsibp。determineCandidateConstructors(beanClass,beanName);if(ctors!null){returnctors;}}}}returnnull;}
  可以看到这个接口是用来解析BeanClass的构造函数的,SmartInstantiationAwareBeanPostProcessor的实现类AutowiredAnnotationBeanPostProcessor,这个类是用来解析确定合适的构造函数,重点解析了Autowired注解,并且还解析了Value注解和Lookup注解。
  当解析出来构造函数之后,那么就调用autowireConstructor方法进行实例化,解析时会new一个构造器解析器ConstructorResolver,在解析factoryMehod时也是使用的这个类使用的是instantiateUsingFactoryMethod这个方法,并且解析factoryMethod更加复杂,需要判断是否是静态的工厂创建还是实例工厂创建,而自动装配的构造解析相对来说简单一些,使用autowireConstructor方法进行解析。
  最终解析出构造方法和构造参数之后进行实例化:使用合适的构造方法和构造参数进行实例化bw。setBeanInstance(instantiate(beanName,mbd,constructorToUse,argsToUse));
  实例化:privateObjectinstantiate(StringbeanName,RootBeanDefinitionmbd,Constructorlt;?constructorToUse,Object〔〕argsToUse){try{获取实例化策略,一般使用CglibSubClassingInstantiationStrategyInstantiationStrategystrategythis。beanFactory。getInstantiationStrategy();if(System。getSecurityManager()!null){returnAccessController。doPrivileged((PrivilegedActionObject)()strategy。instantiate(mbd,beanName,this。beanFactory,constructorToUse,argsToUse),this。beanFactory。getAccessControlContext());}else{开始实例化returnstrategy。instantiate(mbd,beanName,this。beanFactory,constructorToUse,argsToUse);}}catch(Throwableex){thrownewBeanCreationException(mbd。getResourceDescription(),beanName,Beaninstantiationviaconstructorfailed,ex);}}publicObjectinstantiate(RootBeanDefinitionbd,NullableStringbeanName,BeanFactoryowner,finalConstructorlt;?ctor,Object。。。args){if(!bd。hasMethodOverrides()){if(System。getSecurityManager()!null){useownprivilegedtochangeaccessibility(whensecurityison)AccessController。doPrivileged((PrivilegedActionObject)(){ReflectionUtils。makeAccessible(ctor);returnnull;});}实例化类,反射调用returnBeanUtils。instantiateClass(ctor,args);}else{如果方法被覆盖,lookupmethod和replacemethodreturninstantiateWithMethodInjection(bd,beanName,owner,ctor,args);}}
  如果前面的解析都没有到Bean,那么就会使用无参构造函数进行解析:省略代码。。。。Preferredconstructorsfordefaultconstruction?首选的构造器为默认的创建方式,使用了Primary注解的为首选的创建对象方式ctorsmbd。getPreferredConstructors();if(ctors!null){returnautowireConstructor(beanName,mbd,ctors,null);}Nospecialhandling:simplyusenoargconstructor。调用无参构造函数实例化对象returninstantiateBean(beanName,mbd);
  实例化Bean:protectedBeanWrapperinstantiateBean(StringbeanName,RootBeanDefinitionmbd){try{ObjectbeanInstance;if(System。getSecurityManager()!null){beanInstanceAccessController。doPrivileged((PrivilegedActionObject)()getInstantiationStrategy()。instantiate(mbd,beanName,this),getAccessControlContext());}else{实例化对象,使用反射进行创建beanInstancegetInstantiationStrategy()。instantiate(mbd,beanName,this);}创建一个Bean的包装器BeanWrapperbwnewBeanWrapperImpl(beanInstance);初始化Bean的包装器initBeanWrapper(bw);returnbw;}catch(Throwableex){thrownewBeanCreationException(mbd。getResourceDescription(),beanName,Instantiationofbeanfailed,ex);}}
  这里可以看到前面使用factoryMethod和autowireConstructor解析构造函数进行实例化还是使用无参构造函数进行实例化都是将Bean进行了包装,那这个包装有啥作用呢?BeanWrapper的作用
  我们先来看下前面的方法是怎么创建BeanWrapper的:
  factorymethod解析,ConstructorResolverinstantiateUsingFactoryMethod方法:publicBeanWrapperinstantiateUsingFactoryMethod(StringbeanName,RootBeanDefinitionmbd,NullableObject〔〕explicitArgs){创建一个Bean的包装器BeanWrapperImplbwnewBeanWrapperImpl();this。beanFactory。initBeanWrapper(bw);factoryBeanObjectfactoryBean;factory工厂类Classlt;?factoryClass;标识是否是静态的工厂booleanisStatic;省略代码。。。。}
  SmartInstantiationAwareBeanPostProcessor子类AutowiredAnnotationBeanPostProcessor解析出构造函数,然后使用ConstructorResolverautowireConstructor执行:publicBeanWrapperautowireConstructor(StringbeanName,RootBeanDefinitionmbd,NullableConstructorlt;?〔〕chosenCtors,NullableObject〔〕explicitArgs){创建一个包装器BeanWrapperImplbwnewBeanWrapperImpl();初始化包装器this。beanFactory。initBeanWrapper(bw);构造函数Constructorlt;?constructorToUsenull;构造参数ArgumentsHolderargsHolderToUsenull;需要使用的构造参数Object〔〕argsToUsenull;明确的构造参数不为空,则赋值给将要执行实例化的构造参数if(explicitArgs!null){argsToUseexplicitArgs;}省略代码。。。。}
  最终都是会进行转换服务ConversionService和PropertyEditorRegistry的注册,一个是用来进行属性类型转换的,一个是用来属性值解析的:protectedvoidinitBeanWrapper(BeanWrapperbw){获取转换服务放到bean的包装器中bw。setConversionService(getConversionService());注册定制的属性编辑器registerCustomEditors(bw);}
  在前面的文章中,介绍了这两个如何使用,而且还自定义了属性编辑器和类型转换,需要的小伙伴可以去看看:
  https:www。cnblogs。comredwinterp16167214。html和https:www。cnblogs。comredwinterp16241328。html
  到这里Bean的实例化就完成了,接着往下看源码:protectedObjectdoCreateBean(StringbeanName,RootBeanDefinitionmbd,NullableObject〔〕args)throwsBeanCreationException{Instantiatethebean。BeanWrapperinstanceWrappernull;从缓存中获取FactoryBean的Bean对象if(mbd。isSingleton()){instanceWrapperthis。factoryBeanInstanceCache。remove(beanName);}if(instanceWrappernull){实例化对象instanceWrappercreateBeanInstance(beanName,mbd,args);}从包装器中获取Bean对象ObjectbeaninstanceWrapper。getWrappedInstance();从包装器中获取Bean类型Classlt;?beanTypeinstanceWrapper。getWrappedClass();if(beanType!NullBean。class){mbd。resolvedTargetTypebeanType;}Allowpostprocessorstomodifythemergedbeandefinition。synchronized(mbd。postProcessingLock){if(!mbd。postProcessed){try{合并BeanapplyMergedBeanDefinitionPostProcessors(mbd,beanType,beanName);}catch(Throwableex){thrownewBeanCreationException(mbd。getResourceDescription(),beanName,Postprocessingofmergedbeandefinitionfailed,ex);}mbd。postProcessedtrue;}}}
  点进去:protectedvoidapplyMergedBeanDefinitionPostProcessors(RootBeanDefinitionmbd,Classlt;?beanType,StringbeanName){for(BeanPostProcessorbp:getBeanPostProcessors()){if(bpinstanceofMergedBeanDefinitionPostProcessor){MergedBeanDefinitionPostProcessorbdp(MergedBeanDefinitionPostProcessor)bp;执行合并BeanDefinitionbdp。postProcessMergedBeanDefinition(mbd,beanType,beanName);}}}
  可以看到这里出现了一个接口MergedBeanDefinitionPostProcessor,这个接口也是BeanPostProcessor的子接口,那他到底是干啥用的呢?MergedBeanDefinitionPostProcessor接口
  点击发现这个接口的实现类全是跟注解相关的,而最重要的是CommonAnnotationBeanPostProcessor实现类,在构造函数中设置了两个注解:PostConstruct和PreDestroy,一个是在初始化完之后调用,一个是容器销毁时调用。CommonAnnotationBeanPostProcessor这个类的父类为InitDestroyAnnotationBeanPostProcessor,用于处理初始化和销毁方法的。
  CommonAnnotationBeanPostProcessor的构造器:publicCommonAnnotationBeanPostProcessor(){setOrder(Ordered。LOWESTPRECEDENCE3);初始化PostConstructPreDestroy注解调用父类的方法进行设置setInitAnnotationType(PostConstruct。class);setDestroyAnnotationType(PreDestroy。class);ignoreResourceType(javax。xml。ws。WebServiceContext);}
  CommonAnnotationBeanPostProcessor合并方法:publicvoidpostProcessMergedBeanDefinition(RootBeanDefinitionbeanDefinition,Classlt;?beanType,StringbeanName){调用父类super。postProcessMergedBeanDefinition(beanDefinition,beanType,beanName);InjectionMetadatametadatafindResourceMetadata(beanName,beanType,null);metadata。checkConfigMembers(beanDefinition);}
  点击postProcessMergedBeanDefinition方法发现调用了父类的这个方法,然后执行了一个叫查找生命周期元数据的方法findLifecycleMetadata。publicvoidpostProcessMergedBeanDefinition(RootBeanDefinitionbeanDefinition,Classlt;?beanType,StringbeanName){LifecycleMetadatametadatafindLifecycleMetadata(beanType);metadata。checkConfigMembers(beanDefinition);}
  查找生命周期的元数据:privateLifecycleMetadatafindLifecycleMetadata(Classlt;?clazz){if(this。lifecycleMetadataCachenull){Happensafterdeserialization,duringdestruction。。。returnbuildLifecycleMetadata(clazz);}Quickcheckontheconcurrentmapfirst,withminimallocking。查询缓存LifecycleMetadatametadatathis。lifecycleMetadataCache。get(clazz);if(metadatanull){synchronized(this。lifecycleMetadataCache){再次查询metadatathis。lifecycleMetadataCache。get(clazz);if(metadatanull){没有查询到就去构建生命周期的元数据metadatabuildLifecycleMetadata(clazz);this。lifecycleMetadataCache。put(clazz,metadata);}returnmetadata;}}returnmetadata;}
  构建生命周期元数据:privateLifecycleMetadatabuildLifecycleMetadata(finalClasslt;?clazz){这里的initAnnotationType就是子类set进去的PostConstructdestroyAnnotationType就是子类set进去的PreDestroyif(!AnnotationUtils。isCandidateClass(clazz,Arrays。asList(this。initAnnotationType,this。destroyAnnotationType))){returnthis。emptyLifecycleMetadata;}存放初始化方法ListLifecycleElementinitMethodsnewArrayList();存放销毁方法ListLifecycleElementdestroyMethodsnewArrayList();Classlt;?targetClassclazz;do{finalListLifecycleElementcurrInitMethodsnewArrayList();finalListLifecycleElementcurrDestroyMethodsnewArrayList();ReflectionUtils。doWithLocalMethods(targetClass,method{如果找到方法上有PostConstruct注解,这加入到当前初始化方法集合中if(this。initAnnotationType!nullmethod。isAnnotationPresent(this。initAnnotationType)){创建一个生命周期元素LifecycleElementelementnewLifecycleElement(method);currInitMethods。add(newLifecycleElement(method));}如果找到方法上标有PreDestroy注解,就加入到当前销毁方法集合中if(this。destroyAnnotationType!nullmethod。isAnnotationPresent(this。destroyAnnotationType)){currDestroyMethods。add(newLifecycleElement(method));}});赋值到初始化方法集合和销毁方法集合中initMethods。addAll(0,currInitMethods);destroyMethods。addAll(currDestroyMethods);targetClasstargetClass。getSuperclass();}遍历查找while(targetClass!nulltargetClass!Object。class);如果没有解析到,那么返回一个空的生命周期元数据,否则创建一个生命周期元素并放入初始化方法和销毁方法的集合return(initMethods。isEmpty()destroyMethods。isEmpty()?this。emptyLifecycleMetadata:newLifecycleMetadata(clazz,initMethods,destroyMethods));}
  最终发现实际上就是在解析我们的Bean的方法上是否标记了PostConstruct注解和PreDestroy方法,如果有就加入到生命周期元数据中,并且将解析到的方法放入到BeanDefinition的externallyManagedInitMethods和externallyManagedDestroyMethods集合中。
  Bean初始化和销毁方法解析和执行流程如下:
  Bean的合并大概的意思就是做了自定义初始化和销毁方法的解析,并在后期调用BPP时执行。
  SpringBean的实例化基本就解析完了,接下来开始解析循环依赖和Bean的属性填充部分。
  如果本文对你有帮助,别忘记给我个3连,点赞,转发,评论,,咱们下期见。
  收藏等于白嫖,点赞才是真情。
  原文https:www。cnblogs。comredwinterp16268667。html

分析师明年第一季度iPhoneXR将占全部出货量的5010月22日下午消息,据中国台湾地区援引外媒报道称,分析师预期,iPhoneXR的出货量可能比iPhone8系列大约增加50,预期今年第四季iPhoneXR占整体iPhone比……台媒iPhoneXR需求旺盛,苹果向主要供应链追加订单10月22日上午消息,据中国台湾地区媒体报道,业界传出苹果看好iPhoneXR新机销售,近期已向台积电、和硕、可成、GISKY等主要供应链追加订单。报道称,iPhoneX……苹果iPhoneXR美亚促销新招签24月合约获100美元折扣IT之家10月22日消息10月19日下午3:01分,iPhoneXR正式开启了预购,相比于iPhoneXS和iPhoneXSMax的高昂价格,iPhoneXR起售价为6499元……苹果官网已下架iPhoneX,却上架了多款式透明保护壳感谢IT之家网友IT之家高端用户的线索投递!IT之家10月21日消息在今年的新款iPhoneXS、iPhoneXSMax和iPhoneXR发布之后,去年发布的iPhone……Caviar推新款奢华定制版苹果iPhoneXSXSMax4IT之家10月18日消息俄罗斯奢侈定制厂商Caviar推出了GRANDCOMPLICATIONS定制版iPhoneXs和iPhoneXsMax。该机机身饰有雕刻黑色钛金属和雕刻……京东手机会场大促iPhoneXSMax抢券直减1000元IT之家11月11日消息京东手机会场大促,10点可领取满2980减450、满1980减300、满1180减180券,另外整点可抢满4980减1111元神券,满49元可用8折配件……喜报弘正荣获储能行业核心产品及EMS系统双料奖项11月12日,第九届中国国际光储充大会于上海喜来登酒店隆重召开,此次大会由储能领跑者联盟主办,汇聚行业众多企业共襄盛举,大会邀请包括院士团队、发电与电网集团高层领导、储能产业链……苹果iPhoneXR最香,美国Q3iPhone买家中20选择IT之家10月24日消息CIRP表示,其数据表明,2019年第三季度约20的美国iPhone买家选择购买三款iPhone11系列机型之一。CIRP表示,更具预算意识的消费……郭明錤预测苹果iPhoneSE2售价399美元起IT之家10月14日消息本月初,天风国际分析师郭明錤发布新的苹果研究,报告预测苹果将在2020年Q1发售较低售价的iPhoneSE2,大部分外观设计与硬件规格与iPhone8相……摩托罗拉X30Pro使用了7天,不吹不黑,说一下使用感受说实话,我是准备等iPhone14系列发布后,换新iPhone手机的。但看到摩托罗拉X30Pro机型的配置参数非常高,而且12GB256GB只要3999元。不论是从配置来看,还……iPhone11ProMax销量喜人,三星加大OLED面板产IT之家10月22日消息据SamMobile消息,得益于市场表现良好,三星加大了iPhone11Pro和iPhone11ProMax的OLED显示面板的产量。报道称,三星显示器……因售价太贵,苹果砍掉约10的iPhone11ProMax订单IT之家10月13日消息据钛媒体消息,产业链给出的最新内幕显示,苹果对iPhone11ProMax这款型号的订单进行了调整,整体来说就是在之前的基础上下调了约10左右,主要原因……
手机中永久删除掉的图片或文件,还能恢复吗?有哪些影响?手机中永久删除掉的图片或文件,还能恢复吗?有哪些影响?很多用户会删除掉手机中的一些无用的图片与视频,然后这些被删除的图片或视频会移动到最近删除的文件中,仍然会保留30天。那么在……价格差不多的情况下,你是会选择iQOO10Pro还是小米12先说一下,其实这两款手机没有本质上的对比性,因为一个是子品牌,一个是主品牌,但是他们的价格很相近,那么这篇文章我们就来简单的对比一下。先说一下两者的相似之处两者都是……当年,许多长三角人相册里都珍藏着一张大观园打卡照,现在呢?周三上午10:16,青浦大观园内的大观楼前,整修一新的正门上挂着大红绸装饰,游客纷纷在此留影。市民忻女士从手机里翻出一张微微有些发黄的老照片,颇为感慨:这是1998年我们一大家……徐峥风波后首露面回应现状,面部浮肿状态差,网友一夜愁白头众所周知,最近刘畊宏很火,一个直播健身把全网的女孩子都带动起来了。作为一个49岁的中年男人,刘畊宏不仅依旧保持着年轻的状态,而且模样也帅气,带感的健身节奏,也惹得网友们忍不住跟……国内大豆中药材辣椒价格行情中药材价格行情岷县当归城中药材市场当归:今天当归上货量大约有30车,上货量相比以前有所减少。市场人流量基本稳定,整体走货不快,成交价格基本稳定。当归药厂成交价格在4……肾是发色,肝是发根,脾是发质,脏腑好不好,看看头发就知道都说头发是人的第二张脸,每个人都希望自己能有一头乌黑亮丽的秀发,但你知道吗?单看一个人的头发,就能看出这个人脏腑气血的兴衰,今天贾医生就来带大家了解头发的奥秘!我们看一个……俄乌冲突对中国有何影响?中美商会报告7成美企不打算撤出中国这次俄乌冲突中,感受最深的就是中国必须进一步推进全球化贸易,大力对外输出商品,大力吸引外国企业来华投资,这不只是赚钱的问题,将来有一天这都是致胜利器。当一个国家在华企业有……女性应该如何预防痛经的发生通常痛经的发生常由于情志所伤、起居不慎等因素导致,它也是现代女性的比较高发的病种之一。痛经的女性一般会有气血运行不畅的情况,中医常说通则不痛,痛则不通,痛经带来的疼痛感,也对现……套现640亿祖宅被泼油漆,刘强东再转45股权,释放什么信号?衣锦还乡日,他时有此荣。1992年,18岁的刘强东带着全村乡亲东拼西凑的76个茶叶蛋和500学费,穿着破烂的鞋踏上求学之路。多年后,他带着6000亿市值的京东驻扎名不见经……太幸福!中国女排队长传来新消息,朱婷出国途中收获双重大礼世界女排锦标赛小组抽签结果早已出来了!中国女排所在的D组包括巴西,日本,哥伦比亚,阿根廷和捷克。复赛的对手则将于A组的荷兰,意大利,比利时,波多黎各,喀麦隆,肯尼亚6支队伍中产……虎牙梦之队击败KPL队伍!成功复仇KSG,能否晋级破军杯决赛最近,王者荣耀雷霆破军杯正在如火如荼地进行着。这次的比赛看点十足,毕竟虎牙派出了最强的梦之队迎战各大KPL战队,他们的成员是对抗路赖神,打野北慕,中单夏屿,射手口袋以及游走位的……本以为青春哥是个失误,但看到爱情哥和新自来也,事情就清晰了火影忍者手游进入到2021年以后,在经历了年度最强的白面具之后,其他的一些忍者的强度都还是比较正常的,甚至是会出现一些强度翻车的忍者,比如秽土迪达拉。刚开始的秽土迪达拉是真的没……
友情链接:易事利快生活快传网聚热点七猫云快好知快百科中准网快好找文好找中准网快软网