以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 }