以DefaultListableBeanFactory爲例梳理一下BeanFactory接口體系的細節java
BeanFactory(根據註冊的bean定義來生產bean的功能)web
BeanRegistry(bean定義的註冊功能)spring
BeanDefinition(bean的定義信息)app
BeanFactory:用於訪問Spring bean容器的根接口,提供多個重載的getBean方法來獲取註冊到容器中的bean的實例框架
HierarchicalBeanFactory:爲Spring bean 容器提供父子容器的上下層級關係的能力ide
ListableBeanFactory:提供遍歷Spring bean容器中bean的能力但其方法只檢查容器內部bean的定義,而不會真正的實例化bean;而且不會包含其父容器中的bean定義工具
ConfigurableBeanFactory:提供遍歷Spring bean容器的能力,好比向container中增長BeanPostProcessor源碼分析
AutowireCapableBeanFactory:提供自動注入bean屬性的能力,以及其餘框架的集成代碼能夠利用這個接口來鏈接和填充Spring沒法控制的現有bean實例生命週期post
AliasRegistry:用於管理bean別名的接口this
BeanDefinitionRegistry:提供註冊BeanDefinition的能力
AliasRegistry:用於管理bean別名的接口
BeanDefinitionRegistry:提供註冊BeanDefinition的能力
AnnotatedBeanDefinition:註解的元數據
RootBeanDefinition:在Spring bean容器運行期間,經過合併註冊到容器中的bean定義生成的bean元數據
在spring的容器接口體系中,咱們可使用原材料、工廠、生產線操做工人、最終產品的關係來類比BeanDefinition、BeanFactory、BeanRegistry、bean實例。 BeanRegistry提供能力將BeanDefinition註冊到BeanFactory中,BeanFactory經過其內部的生產線來生成bean實例
以AnnotatedGenericBeanDefinition爲例梳理一下BeanDefinition接口實現類體系
Metadata元數據部分在其內部包裝了須要註冊到BeanFactory的類的信息
ClassMetadata,抽象出類的元數據的接口。提供獲取類名、判斷是否爲接口類、是否爲註解類、是否爲抽象類等功能;
AnnotatedTypeMetadata,定義了接口,用於訪問AnnotationMetadata、MethodMetadata這兩個類的註解。提供判斷是否被指定註解標記、獲取指定註解的屬性等功能;
AnnotationMetadata,定義了接口,用於訪問指定類的註解;如getMetaAnnotationTypes(String annotationName)用於獲取指定註解annotationName的元註解集合
StandardClassMetadata,用標準的反射功能實現了ClassMetadata類
StandardAnnotationMetadata,擴展StandardClassMetadata類並實現AnnotationMetadata接口
BeanDefinition做爲註冊到BeanFactory中的載體,在具體的實現類中,持有metadata實例。
AttributeAccessor,定義設置和獲取屬性元數據的接口;
AttributeAccessorSupport,在內部經過LinkedHashMap實現了AttributeAccessor接口;
BeanMetadataElement,持有一個source,具體用途待考究;
BeanMetadataAttribute,實現BeanMetadataElement接口,在其內部以key-value的形式持有bean definition的屬性;
BeanMetadataAttributeAccessor,實現BeanMetadataElement接口,並重寫部分AttributeAccessorSupport的接口,用於設置和獲取BeanMetadataElement;
BeanDefinition,一個BeanDefinition對象用於描述一個bean instance,其中擁有屬性值、構造器屬性值以及更多由其子類提供的信息;
AbstractBeanDefinition:實現了BeanDefinition接口,提供了設置和獲取bean definition中的各個屬性(即類的各類屬性數據)
AnnotatedBeanDefinition,提供接口用於獲取被包裝的類的元數據
GenericBeanDefinition,提供parent bean的設置功能
AnnotatedGenericBeanDefinition,擴展自GenericBeanDefinition,實現AnnotatedBeanDefinition提供暴露註解元數據的支持功能
1 public class AnnotatedBeanDefinitionReader { 2 3 // 省略部分代碼 4 public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) { 5 AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass); 6 if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { 7 return; 8 } 9 // 解析@Scope註解,獲取bean的做用域配置信息 10 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); 11 abd.setScope(scopeMetadata.getScopeName()); 12 String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); 13 // 解析通用註解,如@Lazy等 14 AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); 15 // 定義qualifier信息,主要涉及到後續指定bean注入的註解@Qualifier 16 if (qualifiers != null) { 17 for (Class<? extends Annotation> qualifier : qualifiers) { 18 if (Primary.class == qualifier) { 19 abd.setPrimary(true); 20 } 21 else if (Lazy.class == qualifier) { 22 abd.setLazyInit(true); 23 } 24 else { 25 abd.addQualifier(new AutowireCandidateQualifier(qualifier)); 26 } 27 } 28 } 29 30 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); 31 // 根據ScopeMetadata生成對應的Scope代理 32 definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); 33 // 實際bean的注入,在registry內部用一個ConcurrentHashMap持有了beandefinition信息 34 BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); 35 } 36 37 }
1 // @Scope註解的解析器 2 public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver { 3 4 // 解析@Scope註解,構造ScopeMetadata實例,持有bean做用域的配置信息 5 @Override 6 public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) { 7 ScopeMetadata metadata = new ScopeMetadata(); 8 if (definition instanceof AnnotatedBeanDefinition) { 9 AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition; 10 // 獲取指定註解的屬性值對,此處爲@Scope註解 11 AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor( 12 annDef.getMetadata(), this.scopeAnnotationType); 13 // 若是屬性不爲null,則根據屬性值對修改ScopeMetadata的值 14 if (attributes != null) { 15 metadata.setScopeName(attributes.getString("value")); 16 ScopedProxyMode proxyMode = attributes.getEnum("proxyMode"); 17 if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) { 18 proxyMode = this.defaultProxyMode; 19 } 20 metadata.setScopedProxyMode(proxyMode); 21 } 22 } 23 return metadata; 24 } 25 26 } 27 28 // 註解配置信息的輔助工具類 29 public class AnnotationConfigUtils { 30 31 // 獲取metadata中,annotationClass註解類型的屬性值,用AnnotationAttributes(繼承自LinkedHashMap,額外保存了註解類型等信息)持有 32 static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class<?> annotationClass) { 33 return attributesFor(metadata, annotationClass.getName()); 34 } 35 36 // 獲取metadata中,annotationClass註解類型的屬性值,用AnnotationAttributes(繼承自LinkedHashMap,額外保存了註解類型等信息)持有 37 static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) { 38 return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false)); 39 } 40 41 } 42 43 // 持有類的元數據 44 public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata { 45 46 // 獲取指定註解名annotationName中的屬性值對 47 @Override 48 public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) { 49 return (this.annotations.length > 0 ? AnnotatedElementUtils.getMergedAnnotationAttributes( 50 getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap) : null); 51 } 52 53 } 54 55 // 用於在AnnotatedElement上查找註解、元註解、可重複註解的工具類 56 public class AnnotatedElementUtils { 57 58 public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, 59 String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) { 60 61 Assert.hasLength(annotationName, "'annotationName' must not be null or empty"); 62 // 根據註解名查找註解的屬性值對 63 AnnotationAttributes attributes = searchWithGetSemantics(element, null, annotationName, 64 new MergedAnnotationAttributesProcessor(classValuesAsString, nestedAnnotationsAsMap)); 65 66 // 處理註解別名 67 AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap); 68 return attributes; 69 } 70 71 private static <T> T searchWithGetSemantics(AnnotatedElement element, 72 Class<? extends Annotation> annotationType, String annotationName, Processor<T> processor) { 73 // 將查找工做,轉發給processor處理(Processor -> MergedAnnotationAttributesProcessor) 74 return searchWithGetSemantics(element, annotationType, annotationName, null, processor); 75 } 76 77 private static <T> T searchWithGetSemantics(AnnotatedElement element, 78 Class<? extends Annotation> annotationType, String annotationName, 79 Class<? extends Annotation> containerType, Processor<T> processor) { 80 81 try { 82 // 進行第一層查找(metaDepth=0) 83 return searchWithGetSemantics(element, annotationType, annotationName, 84 containerType, processor, new HashSet<AnnotatedElement>(), 0); 85 } 86 catch (Throwable ex) { 87 AnnotationUtils.rethrowAnnotationConfigurationException(ex); 88 throw new IllegalStateException("Failed to introspect annotations on " + element, ex); 89 } 90 } 91 92 private static <T> T searchWithGetSemantics(AnnotatedElement element, 93 Class<? extends Annotation> annotationType, String annotationName, 94 Class<? extends Annotation> containerType, Processor<T> processor, 95 Set<AnnotatedElement> visited, int metaDepth) { 96 97 Assert.notNull(element, "AnnotatedElement must not be null"); 98 99 if (visited.add(element)) { 100 try { 101 // Start searching within locally declared annotations 102 List<Annotation> declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations()); 103 // 轉發給重載方法,進行實際的查找操做 104 T result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations, 105 annotationType, annotationName, containerType, processor, visited, metaDepth); 106 if (result != null) { 107 return result; 108 } 109 110 if (element instanceof Class) { // otherwise getAnnotations does not return anything new 111 List<Annotation> inheritedAnnotations = new ArrayList<Annotation>(); 112 for (Annotation annotation : element.getAnnotations()) { 113 if (!declaredAnnotations.contains(annotation)) { 114 inheritedAnnotations.add(annotation); 115 } 116 } 117 118 // Continue searching within inherited annotations 119 result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations, 120 annotationType, annotationName, containerType, processor, visited, metaDepth); 121 if (result != null) { 122 return result; 123 } 124 } 125 } 126 catch (Throwable ex) { 127 AnnotationUtils.handleIntrospectionFailure(element, ex); 128 } 129 } 130 131 return null; 132 } 133 134 // 執行實際的註解屬性查找功能 135 private static <T> T searchWithGetSemanticsInAnnotations(AnnotatedElement element, 136 List<Annotation> annotations, Class<? extends Annotation> annotationType, 137 String annotationName, Class<? extends Annotation> containerType, 138 Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) { 139 140 // Search in annotations 141 // 遍歷註解列表 142 for (Annotation annotation : annotations) { 143 Class<? extends Annotation> currentAnnotationType = annotation.annotationType(); 144 // 只處理非JDK內置的註解 145 if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) { 146 // 知足如下任意條件,須要調用processor.process(element, annotation, metaDepth)方法進行屬性值的查找工做 147 // 1. 若是當前循環的註解,爲咱們指定的註解類型 148 // 2. 若是當前循環的註解,爲咱們指定的註解名稱 149 // 3. 始終調用processor,即processor.alwaysProcesses()返回true 150 if (currentAnnotationType == annotationType || 151 currentAnnotationType.getName().equals(annotationName) || 152 processor.alwaysProcesses()) { 153 // 查找註解屬性值 154 T result = processor.process(element, annotation, metaDepth); 155 if (result != null) { 156 157 if (processor.aggregates() && metaDepth == 0) { 158 // 聚合查找結果 159 processor.getAggregatedResults().add(result); 160 } 161 else { 162 return result; 163 } 164 } 165 } 166 // Repeatable annotations in container? 167 else if (currentAnnotationType == containerType) { 168 for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) { 169 T result = processor.process(element, contained, metaDepth); 170 if (result != null) { 171 // No need to post-process since repeatable annotations within a 172 // container cannot be composed annotations. 173 processor.getAggregatedResults().add(result); 174 } 175 } 176 } 177 } 178 } 179 180 // Recursively search in meta-annotations 181 for (Annotation annotation : annotations) { 182 Class<? extends Annotation> currentAnnotationType = annotation.annotationType(); 183 if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) { 184 T result = searchWithGetSemantics(currentAnnotationType, annotationType, 185 annotationName, containerType, processor, visited, metaDepth + 1); 186 if (result != null) { 187 processor.postProcess(element, annotation, result); 188 if (processor.aggregates() && metaDepth == 0) { 189 processor.getAggregatedResults().add(result); 190 } 191 else { 192 return result; 193 } 194 } 195 } 196 } 197 198 return null; 199 } 200 201 } 202 203 private static class MergedAnnotationAttributesProcessor implements Processor<AnnotationAttributes> { 204 205 @Override 206 public AnnotationAttributes process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) { 207 return AnnotationUtils.retrieveAnnotationAttributes(annotatedElement, annotation, 208 this.classValuesAsString, this.nestedAnnotationsAsMap); 209 } 210 211 } 212 213 214 public abstract class AnnotationUtils { 215 216 // 將註解屬性值包裝爲AnnotationAttributes,返回給上層調用 217 static AnnotationAttributes retrieveAnnotationAttributes(Object annotatedElement, Annotation annotation, 218 boolean classValuesAsString, boolean nestedAnnotationsAsMap) { 219 220 Class<? extends Annotation> annotationType = annotation.annotationType(); 221 AnnotationAttributes attributes = new AnnotationAttributes(annotationType); 222 223 for (Method method : getAttributeMethods(annotationType)) { 224 try { 225 Object attributeValue = method.invoke(annotation); 226 Object defaultValue = method.getDefaultValue(); 227 if (defaultValue != null && ObjectUtils.nullSafeEquals(attributeValue, defaultValue)) { 228 attributeValue = new DefaultValueHolder(defaultValue); 229 } 230 attributes.put(method.getName(), 231 adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap)); 232 } 233 catch (Throwable ex) { 234 if (ex instanceof InvocationTargetException) { 235 Throwable targetException = ((InvocationTargetException) ex).getTargetException(); 236 rethrowAnnotationConfigurationException(targetException); 237 } 238 throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex); 239 } 240 } 241 242 return attributes; 243 } 244 245 }
在spring的高版本中,官方建議開發者使用java code的配置方式。其原理主要是利用ConfigurationClassPostProcessor類來進行解析。執行的時機發生在容器啓動後,調用invokeBeanFactoryPostProcessors()方法這一步。
1 public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, 2 PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware { 3 4 public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { 5 List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>(); 6 String[] candidateNames = registry.getBeanDefinitionNames(); 7 8 // 遍歷beanfactory中全部已註冊的bean 9 for (String beanName : candidateNames) { 10 BeanDefinition beanDef = registry.getBeanDefinition(beanName); 11 // 判斷是否爲處理過的full配置類 12 if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) || 13 // 判斷是否爲處理過的lite配置類 14 ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) { 15 if (logger.isDebugEnabled()) { 16 logger.debug("Bean definition has already been processed as a configuration class: " + beanDef); 17 } 18 } 19 // 判斷是否爲配置類(標註了@Configuration、@Component、@ComponentScan、@Import、@ImportResource) 20 // 爲full配置類時,爲beanDef增長鍵爲org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass,值爲full的attribute 21 // 爲lite配置類時,爲beanDef增長鍵爲org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass,值爲lite的attribute 22 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { 23 configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); 24 } 25 } 26 27 // Return immediately if no @Configuration classes were found 28 if (configCandidates.isEmpty()) { 29 return; 30 } 31 32 // Sort by previously determined @Order value, if applicable 33 // 配置類能夠按照順序加載 34 Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() { 35 @Override 36 public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) { 37 int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition()); 38 int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition()); 39 return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0; 40 } 41 }); 42 43 // Detect any custom bean name generation strategy supplied through the enclosing application context 44 SingletonBeanRegistry sbr = null; 45 if (registry instanceof SingletonBeanRegistry) { 46 sbr = (SingletonBeanRegistry) registry; 47 if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) { 48 BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR); 49 this.componentScanBeanNameGenerator = generator; 50 this.importBeanNameGenerator = generator; 51 } 52 } 53 54 // Parse each @Configuration class 55 ConfigurationClassParser parser = new ConfigurationClassParser( 56 this.metadataReaderFactory, this.problemReporter, this.environment, 57 this.resourceLoader, this.componentScanBeanNameGenerator, registry); 58 59 Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates); 60 Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size()); 61 do { 62 // 解析配置類,完成這一步流程後,在其內部對各類配置信息,包裝爲一個ConfigurationClass的集合 63 // 在加載bean的過程當中,實際上也是對這個集合進行各類操做,如:從@Bean方法加載bean、@Import導入配置等等 64 parser.parse(candidates); 65 parser.validate(); 66 67 Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses()); 68 configClasses.removeAll(alreadyParsed); 69 70 // Read the model and create bean definitions based on its content 71 if (this.reader == null) { 72 this.reader = new ConfigurationClassBeanDefinitionReader( 73 registry, this.sourceExtractor, this.resourceLoader, this.environment, 74 this.importBeanNameGenerator, parser.getImportRegistry()); 75 } 76 // 對ConfigurationClassParser持有的配置信息集合進行bean的加載。 77 // 至此,須要註冊到IOC容器的全部bean都已註冊完畢 78 this.reader.loadBeanDefinitions(configClasses); 79 alreadyParsed.addAll(configClasses); 80 81 candidates.clear(); 82 if (registry.getBeanDefinitionCount() > candidateNames.length) { 83 String[] newCandidateNames = registry.getBeanDefinitionNames(); 84 Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames)); 85 Set<String> alreadyParsedClasses = new HashSet<String>(); 86 for (ConfigurationClass configurationClass : alreadyParsed) { 87 alreadyParsedClasses.add(configurationClass.getMetadata().getClassName()); 88 } 89 for (String candidateName : newCandidateNames) { 90 if (!oldCandidateNames.contains(candidateName)) { 91 BeanDefinition bd = registry.getBeanDefinition(candidateName); 92 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && 93 !alreadyParsedClasses.contains(bd.getBeanClassName())) { 94 candidates.add(new BeanDefinitionHolder(bd, candidateName)); 95 } 96 } 97 } 98 candidateNames = newCandidateNames; 99 } 100 } 101 while (!candidates.isEmpty()); 102 103 // Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes 104 if (sbr != null) { 105 if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) { 106 sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry()); 107 } 108 } 109 110 if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) { 111 ((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache(); 112 } 113 } 114 115 }