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