This is an analysis of the Spring Bean attribute injection code Populatebean, the source analysis is as follows
/*** Populate The Bean instance in the given Beanwrapper and the property values * from the bean definition. * Enrich Bean Instance Properties *@paramBeanname The name of the bean *@paramMBD The bean definition for the bean *@parambw Beanwrapper with Bean instance*/ protected voidPopulatebean (String beanname, rootbeandefinition mbd, @Nullable beanwrapper bw) {propertyvalues PVs=mbd.getpropertyvalues (); if(BW = =NULL) { if(!Pvs.isempty ()) { Throw Newbeancreationexception (Mbd.getresourcedescription (), Beanname,"Cannot apply property values to null instance"); } Else { //Skip Property Population phase for null instance. return; } } //Give any instantiationawarebeanpostprocessors the opportunity to modify the//State of the bean before properties is set. This can is used, for example,//To the support styles of field injection. //call the processor before the property is set BooleanContinuewithpropertypopulation =true; if(!mbd.issynthetic () &&hasinstantiationawarebeanpostprocessors ()) { for(Beanpostprocessor bp:getbeanpostprocessors ()) {if(BPinstanceofinstantiationawarebeanpostprocessor) {Instantiationawarebeanpostprocessor IBP=(Instantiationawarebeanpostprocessor) BP; if(!ibp.postprocessafterinstantiation (Bw.getwrappedinstance (), beanname)) {continuewithpropertypopulation=false; Break; } } } } if(!continuewithpropertypopulation) { return; } if(Mbd.getresolvedautowiremode () = = Rootbeandefinition.autowire_by_name | |Mbd.getresolvedautowiremode ()==Rootbeandefinition.autowire_by_type) {mutablepropertyvalues Newpvs=Newmutablepropertyvalues (PVS); //Add property values based on Autowire by name if applicable. if(Mbd.getresolvedautowiremode () = =rootbeandefinition.autowire_by_name) {Autowirebyname (beanname, MBD, BW, Newpvs); } //Add property values based on Autowire by type if applicable. if(Mbd.getresolvedautowiremode () = =Rootbeandefinition.autowire_by_type) {Autowirebytype (beanname, MBD, BW, Newpvs); } PVs=Newpvs; } BooleanHasinstawarebpps =hasinstantiationawarebeanpostprocessors (); BooleanNeedsdepcheck = (Mbd.getdependencycheck ()! =Rootbeandefinition.dependency_check_none); //Set Bean Properties if(Hasinstawarebpps | |Needsdepcheck) {propertydescriptor[] Filteredpds=Filterpropertydescriptorsfordependencycheck (BW, mbd.allowcaching); if(Hasinstawarebpps) { for(Beanpostprocessor bp:getbeanpostprocessors ()) {if(BPinstanceofinstantiationawarebeanpostprocessor) {Instantiationawarebeanpostprocessor IBP=(Instantiationawarebeanpostprocessor) BP; PVs=ibp.postprocesspropertyvalues (PVs, Filteredpds, Bw.getwrappedinstance (), beanname); if(PVs = =NULL) { return; } } } } if(Needsdepcheck) {checkdependencies (Beanname, MBD, Filteredpds, PVS); }} applypropertyvalues (Beanname, MBD, BW, PVS); }
During the debug process we know that there are 7 beanpostprocessor in total
For @autowired, the attribute value injected by the @Value annotation is autowiredannotationbeanpostprocessor processed. We further analyze the code for Autowiredannotationbeanpostprocessor injection properties
/*** autowired Attribute injection *@authorCoshaho *@paramPVs *@paramPDS Injection Property configuration, not used in method *@paramBean Bean Instance *@paramBeanname *@return * @throwsbeancreationexception*/ Publicpropertyvalues postprocesspropertyvalues (propertyvalues PVs, propertydescriptor[] pds, Object Bean, Strin G Beanname)throwsbeancreationexception {//Get Injection Property configuration informationInjectionmetadata metadata =Findautowiringmetadata (Beanname, Bean.getclass (), PVS); Try { //Attribute Injectionmetadata.inject (Bean, beanname, PVS); } Catch(Beancreationexception ex) {Throwex; } Catch(Throwable ex) {Throw NewBeancreationexception (Beanname, "Injection of autowired dependencies failed", ex); } returnPVs; } Public voidInject (Object target, @Nullable String beanname, @Nullable propertyvalues PVs)throwsThrowable {//get the property queue to be injectedCollection<injectedelement> checkedelements = This. checkedelements; Collection<InjectedElement> elementstoiterate =(checkedelements!=NULL? Checkedelements: This. injectedelements); if(!Elementstoiterate.isempty ()) { Booleandebug =logger.isdebugenabled (); for(injectedelement element:elementstoiterate) {if(Debug) {Logger.debug ("Processing injected element of bean '" + beanname + "':" +element); } //Attribute InjectionElement.inject (Target, Beanname, PVS); } } }
Injectionmetadata is the bean injection property configuration, Injectionelement is a single injection property configuration, and Injectionelement.inject is a single attribute injection method. Injectionelement.inject calls the Defaultlistablebeanfactory.doresolvedependency method to get the property value
@Overrideprotected voidInject (Object bean, @Nullable String beanname, @Nullable propertyvalues PVs)throwsthrowable {Field field= (Field) This. Member; Object value; if( This. Cached) {Value= Resolvedcachedargument (Beanname, This. Cachedfieldvalue); } Else { //Get Injection Property Configuration: Property name, class nameDependencydescriptor desc =NewDependencydescriptor (field, This. required); Desc.setcontainingclass (Bean.getclass ()); Set<String> Autowiredbeannames =NewLinkedhashset<> (1); Assert.state (Beanfactory!=NULL, "No beanfactory available"); TypeConverter TypeConverter=Beanfactory.gettypeconverter (); Try { //Get Property valueValue =beanfactory.resolvedependency (DESC, Beanname, Autowiredbeannames, TypeConverter); } Catch(Beansexception ex) {Throw NewUnsatisfieddependencyexception (NULL, Beanname,Newinjectionpoint (field), ex); } synchronized( This) { if(! This. Cached) { if(Value! =NULL|| This. Required) { This. Cachedfieldvalue =desc; Registerdependentbeans (Beanname, autowiredbeannames); if(autowiredbeannames.size () = = 1) {String autowiredbeanname=Autowiredbeannames.iterator (). Next (); if(Beanfactory.containsbean (autowiredbeanname)) {if(Beanfactory.istypematch (Autowiredbeanname, Field.gettype ())) { This. Cachedfieldvalue =Newshortcutdependencydescriptor (DESC, Autowiredbeanname, Field.gettype ()); } } } } Else { This. Cachedfieldvalue =NULL; } This. cached =true; } } } if(Value! =NULL) {reflectionutils.makeaccessible (field); //Reflection Settings PropertiesField.set (bean, value); } } PublicObject resolvedependency (dependencydescriptor descriptor, @Nullable String requestingbeanname, @Nullable S ET<String> autowiredbeannames, @Nullable TypeConverter TypeConverter)throwsbeansexception {descriptor.initparameternamediscovery (Getparameternamediscoverer ()); if(Optional.class==Descriptor.getdependencytype ()) { returncreateoptionaldependency (descriptor, requestingbeanname); } Else if(Objectfactory.class= = Descriptor.getdependencytype () | |Objectprovider.class==Descriptor.getdependencytype ()) { return NewDependencyobjectprovider (descriptor, requestingbeanname); } Else if(Javaxinjectproviderclass = =Descriptor.getdependencytype ()) { return Newjsr330providerfactory (). Createdependencyprovider (descriptor, requestingbeanname); } Else{Object result=getautowirecandidateresolver (). Getlazyresolutionproxyifnecessary (descriptor, requestingbeanname); if(Result = =NULL) { //Get injected valueresult =doresolvedependency (descriptor, Requestingbeanname, Autowiredbeannames, TypeConverter); } returnresult; } }
Spring source Reading (vi)