Spring IOC:BeanDefinition加载注册流程(转)

BeanFactory接口体系

以DefaultListableBeanFactory为例梳理一下BeanFactory接口体系的细节

img

主要接口、抽象类的作用如下:

  1. BeanFactory(根据注册的bean定义来生产bean的功能)

  2. BeanRegistry(bean定义的注册功能)

  3. BeanDefinition(bean的定义信息)

BeanFactory

  1. BeanFactory:用于访问Spring bean容器的根接口,提供多个重载的getBean方法来获取注册到容器中的bean的实例

  2. HierarchicalBeanFactory:为Spring bean 容器提供父子容器的上下层级关系的能力

  3. ListableBeanFactory:提供遍历Spring bean容器中bean的能力但其方法只检查容器内部bean的定义,而不会真正的实例化bean;并且不会包含其父容器中的bean定义

  4. ConfigurableBeanFactory:提供遍历Spring bean容器的能力,比如向container中增加BeanPostProcessor

  5. AutowireCapableBeanFactory:提供自动注入bean属性的能力,以及其他框架的集成代码可以利用这个接口来连接和填充Spring无法控制的现有bean实例生命周期

BeanRegistry

  1. AliasRegistry:用于管理bean别名的接口

  2. BeanDefinitionRegistry:提供注册BeanDefinition的能力

BeanRegistry

  1. AliasRegistry:用于管理bean别名的接口

  2. BeanDefinitionRegistry:提供注册BeanDefinition的能力

BeanDefinition

  1. AnnotatedBeanDefinition:注解的元数据

  2. RootBeanDefinition:在Spring bean容器运行期间,通过合并注册到容器中的bean定义生成的bean元数据

总结

在spring的容器接口体系中,我们可以使用原材料、工厂、生产线操作工人、最终产品的关系来类比BeanDefinition、BeanFactory、BeanRegistry、bean实例。 BeanRegistry提供能力将BeanDefinition注册到BeanFactory中,BeanFactory通过其内部的生产线来生成bean实例

 

BeanDefinition的接口实现类体系

以AnnotatedGenericBeanDefinition为例梳理一下BeanDefinition接口实现类体系

Metadata元数据部分

Metadata元数据部分在其内部包装了需要注册到BeanFactory的类的信息

类图

img

类关系说明

  1. ClassMetadata,抽象出类的元数据的接口。提供获取类名、判断是否为接口类、是否为注解类、是否为抽象类等功能;

  2. AnnotatedTypeMetadata,定义了接口,用于访问AnnotationMetadata、MethodMetadata这两个类的注解。提供判断是否被指定注解标记、获取指定注解的属性等功能;

  3. AnnotationMetadata,定义了接口,用于访问指定类的注解;如getMetaAnnotationTypes(String annotationName)用于获取指定注解annotationName的元注解集合

  4. StandardClassMetadata,用标准的反射功能实现了ClassMetadata类

  5. StandardAnnotationMetadata,扩展StandardClassMetadata类并实现AnnotationMetadata接口

BeanDefinition部分

BeanDefinition作为注册到BeanFactory中的载体,在具体的实现类中,持有metadata实例。

类图

img

类关系说明

  1. AttributeAccessor,定义设置和获取属性元数据的接口;

  2. AttributeAccessorSupport,在内部通过LinkedHashMap实现了AttributeAccessor接口;

  3. BeanMetadataElement,持有一个source,具体用途待考究;

  4. BeanMetadataAttribute,实现BeanMetadataElement接口,在其内部以key-value的形式持有bean definition的属性;

  5. BeanMetadataAttributeAccessor,实现BeanMetadataElement接口,并重写部分AttributeAccessorSupport的接口,用于设置和获取BeanMetadataElement;

  6. BeanDefinition,一个BeanDefinition对象用于描述一个bean instance,其中拥有属性值、构造器属性值以及更多由其子类提供的信息;

  7. AbstractBeanDefinition:实现了BeanDefinition接口,提供了设置和获取bean definition中的各个属性(即类的各种属性数据)

  8. AnnotatedBeanDefinition,提供接口用于获取被包装的类的元数据

  9. GenericBeanDefinition,提供parent bean的设置功能

  10. AnnotatedGenericBeanDefinition,扩展自GenericBeanDefinition,实现AnnotatedBeanDefinition提供暴露注解元数据的支持功能

 

注册注解配置类流程

主流程

 

img

源码分析

 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 }

解析@Scope的流程,分析spring解析注解类属性值的流程

主流程

 

img

 

源码分析

  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 }

基于注解配置,注册bean的原理

在spring的高版本中,官方建议开发者使用java code的配置方式。其原理主要是利用ConfigurationClassPostProcessor类来进行解析。执行的时机发生在容器启动后,调用invokeBeanFactoryPostProcessors()方法这一步。

主流程

img

源码分析

  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 }

 

猜你喜欢

转载自www.cnblogs.com/magic-sea/p/11701478.html
今日推荐