spring-IOC容器源码分析(二)BeanDefinition注册流程

本篇文章主要介绍如下几个部分:java

  1. BeanFactory接口体系
  2. BeanDefinition的接口实现类体系
  3. 梳理注册注解配置类流程
  4. 从解析@Scope的流程入手,分析一个通用的spring解析注解属性的流程
  5. java code config基于注解配置的原理

BeanFactory接口体系

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

主要接口、抽象类的做用以下:

  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的能力

BeanDefinition

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

总结

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

BeanDefinition的接口实现类体系

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

Metadata元数据部分

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

类图

类关系说明

  1. ClassMetadata,抽象出类的元数据的接口。提供获取类名、判断是否为接口类、是否为注解类、是否为抽象类等功能;
  2. AnnotatedTypeMetadata,定义了接口,用于访问AnnotationMetadata、MethodMetadata这两个类的注解。提供判断是否被指定注解标记、获取指定注解的属性等功能;
  3. AnnotationMetadata,定义了接口,用于访问指定类的注解;如getMetaAnnotationTypes(String annotationName)用于获取指定注解annotationName的元注解集合
  4. StandardClassMetadata,用标准的反射功能实现了ClassMetadata类
  5. StandardAnnotationMetadata,扩展StandardClassMetadata类并实现AnnotationMetadata接口

BeanDefinition部分

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

类图

类关系说明

  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提供暴露注解元数据的支持功能

注册注解配置类流程

主流程

源码分析

public class AnnotatedBeanDefinitionReader {

    // 省略部分代码
    public void registerBean(Class<?> annotatedClass, String name, Class<? extends Annotation>... qualifiers) {
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}
        // 解析@Scope注解,获取bean的做用域配置信息
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
        // 解析通用注解,如@Lazy等
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
        // 定义qualifier信息,主要涉及到后续指定bean注入的注解@Qualifier
		if (qualifiers != null) {
			for (Class<? extends Annotation> qualifier : qualifiers) {
				if (Primary.class == qualifier) {
					abd.setPrimary(true);
				}
				else if (Lazy.class == qualifier) {
					abd.setLazyInit(true);
				}
				else {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        // 根据ScopeMetadata生成对应的Scope代理
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
        // 实际bean的注入,在registry内部用一个ConcurrentHashMap持有了beandefinition信息
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

}
复制代码

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

主流程

源码分析

// @Scope注解的解析器
public class AnnotationScopeMetadataResolver implements ScopeMetadataResolver {

    // 解析@Scope注解,构造ScopeMetadata实例,持有bean做用域的配置信息
    @Override
	public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
		ScopeMetadata metadata = new ScopeMetadata();
		if (definition instanceof AnnotatedBeanDefinition) {
			AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
            // 获取指定注解的属性值对,此处为@Scope注解
			AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
					annDef.getMetadata(), this.scopeAnnotationType);
            // 若是属性不为null,则根据属性值对修改ScopeMetadata的值
			if (attributes != null) {
				metadata.setScopeName(attributes.getString("value"));
				ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
				if (proxyMode == null || proxyMode == ScopedProxyMode.DEFAULT) {
					proxyMode = this.defaultProxyMode;
				}
				metadata.setScopedProxyMode(proxyMode);
			}
		}
		return metadata;
	}

}

// 注解配置信息的辅助工具类
public class AnnotationConfigUtils {

    // 获取metadata中,annotationClass注解类型的属性值,用AnnotationAttributes(继承自LinkedHashMap,额外保存了注解类型等信息)持有
    static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, Class<?> annotationClass) {
		return attributesFor(metadata, annotationClass.getName());
	}

    // 获取metadata中,annotationClass注解类型的属性值,用AnnotationAttributes(继承自LinkedHashMap,额外保存了注解类型等信息)持有
    static AnnotationAttributes attributesFor(AnnotatedTypeMetadata metadata, String annotationClassName) {
		return AnnotationAttributes.fromMap(metadata.getAnnotationAttributes(annotationClassName, false));
	}

}

// 持有类的元数据
public class StandardAnnotationMetadata extends StandardClassMetadata implements AnnotationMetadata {

    // 获取指定注解名annotationName中的属性值对
    @Override
	public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) {
		return (this.annotations.length > 0 ? AnnotatedElementUtils.getMergedAnnotationAttributes(
				getIntrospectedClass(), annotationName, classValuesAsString, this.nestedAnnotationsAsMap) : null);
	}

}

// 用于在AnnotatedElement上查找注解、元注解、可重复注解的工具类
public class AnnotatedElementUtils {

    public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, String annotationName, boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

		Assert.hasLength(annotationName, "'annotationName' must not be null or empty");
        // 根据注解名查找注解的属性值对
		AnnotationAttributes attributes = searchWithGetSemantics(element, null, annotationName,
				new MergedAnnotationAttributesProcessor(classValuesAsString, nestedAnnotationsAsMap));

        // 处理注解别名
		AnnotationUtils.postProcessAnnotationAttributes(element, attributes, classValuesAsString, nestedAnnotationsAsMap);
		return attributes;
	}

    private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType, String annotationName, Processor<T> processor) {
        // 将查找工做,转发给processor处理(Processor -> MergedAnnotationAttributesProcessor)
		return searchWithGetSemantics(element, annotationType, annotationName, null, processor);
	}

    private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType, String annotationName, Class<? extends Annotation> containerType, Processor<T> processor) {

		try {
            // 进行第一层查找(metaDepth=0)
			return searchWithGetSemantics(element, annotationType, annotationName,
					containerType, processor, new HashSet<AnnotatedElement>(), 0);
		}
		catch (Throwable ex) {
			AnnotationUtils.rethrowAnnotationConfigurationException(ex);
			throw new IllegalStateException("Failed to introspect annotations on " + element, ex);
		}
	}

    private static <T> T searchWithGetSemantics(AnnotatedElement element, Class<? extends Annotation> annotationType, String annotationName, Class<? extends Annotation> containerType, Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {

		Assert.notNull(element, "AnnotatedElement must not be null");

		if (visited.add(element)) {
			try {
				// Start searching within locally declared annotations
				List<Annotation> declaredAnnotations = Arrays.asList(element.getDeclaredAnnotations());
                // 转发给重载方法,进行实际的查找操做
				T result = searchWithGetSemanticsInAnnotations(element, declaredAnnotations,
						annotationType, annotationName, containerType, processor, visited, metaDepth);
				if (result != null) {
					return result;
				}

				if (element instanceof Class) {  // otherwise getAnnotations does not return anything new
					List<Annotation> inheritedAnnotations = new ArrayList<Annotation>();
					for (Annotation annotation : element.getAnnotations()) {
						if (!declaredAnnotations.contains(annotation)) {
							inheritedAnnotations.add(annotation);
						}
					}

					// Continue searching within inherited annotations
					result = searchWithGetSemanticsInAnnotations(element, inheritedAnnotations,
							annotationType, annotationName, containerType, processor, visited, metaDepth);
					if (result != null) {
						return result;
					}
				}
			}
			catch (Throwable ex) {
				AnnotationUtils.handleIntrospectionFailure(element, ex);
			}
		}

		return null;
	}

    // 执行实际的注解属性查找功能
    private static <T> T searchWithGetSemanticsInAnnotations(AnnotatedElement element, List<Annotation> annotations, Class<? extends Annotation> annotationType, String annotationName, Class<? extends Annotation> containerType, Processor<T> processor, Set<AnnotatedElement> visited, int metaDepth) {

		// Search in annotations
        // 遍历注解列表
		for (Annotation annotation : annotations) {
			Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
            // 只处理非JDK内置的注解
			if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
                // 知足如下任意条件,须要调用processor.process(element, annotation, metaDepth)方法进行属性值的查找工做
                // 1. 若是当前循环的注解,为咱们指定的注解类型
                // 2. 若是当前循环的注解,为咱们指定的注解名称
                // 3. 始终调用processor,即processor.alwaysProcesses()返回true
				if (currentAnnotationType == annotationType ||
						currentAnnotationType.getName().equals(annotationName) ||
						processor.alwaysProcesses()) {
                    // 查找注解属性值
					T result = processor.process(element, annotation, metaDepth);
					if (result != null) {
                        
						if (processor.aggregates() && metaDepth == 0) {
                            // 聚合查找结果
							processor.getAggregatedResults().add(result);
						}
						else {
							return result;
						}
					}
				}
				// Repeatable annotations in container?
				else if (currentAnnotationType == containerType) {
					for (Annotation contained : getRawAnnotationsFromContainer(element, annotation)) {
						T result = processor.process(element, contained, metaDepth);
						if (result != null) {
							// No need to post-process since repeatable annotations within a
							// container cannot be composed annotations.
							processor.getAggregatedResults().add(result);
						}
					}
				}
			}
		}

		// Recursively search in meta-annotations
		for (Annotation annotation : annotations) {
			Class<? extends Annotation> currentAnnotationType = annotation.annotationType();
			if (!AnnotationUtils.isInJavaLangAnnotationPackage(currentAnnotationType)) {
				T result = searchWithGetSemantics(currentAnnotationType, annotationType,
						annotationName, containerType, processor, visited, metaDepth + 1);
				if (result != null) {
					processor.postProcess(element, annotation, result);
					if (processor.aggregates() && metaDepth == 0) {
						processor.getAggregatedResults().add(result);
					}
					else {
						return result;
					}
				}
			}
		}

		return null;
	}

}

private static class MergedAnnotationAttributesProcessor implements Processor<AnnotationAttributes> {

    @Override
    public AnnotationAttributes process(AnnotatedElement annotatedElement, Annotation annotation, int metaDepth) {
        return AnnotationUtils.retrieveAnnotationAttributes(annotatedElement, annotation,
                this.classValuesAsString, this.nestedAnnotationsAsMap);
    }

}


public abstract class AnnotationUtils {

    // 将注解属性值包装为AnnotationAttributes,返回给上层调用
    static AnnotationAttributes retrieveAnnotationAttributes(Object annotatedElement, Annotation annotation, boolean classValuesAsString, boolean nestedAnnotationsAsMap) {

		Class<? extends Annotation> annotationType = annotation.annotationType();
		AnnotationAttributes attributes = new AnnotationAttributes(annotationType);

		for (Method method : getAttributeMethods(annotationType)) {
			try {
				Object attributeValue = method.invoke(annotation);
				Object defaultValue = method.getDefaultValue();
				if (defaultValue != null && ObjectUtils.nullSafeEquals(attributeValue, defaultValue)) {
					attributeValue = new DefaultValueHolder(defaultValue);
				}
				attributes.put(method.getName(),
						adaptValue(annotatedElement, attributeValue, classValuesAsString, nestedAnnotationsAsMap));
			}
			catch (Throwable ex) {
				if (ex instanceof InvocationTargetException) {
					Throwable targetException = ((InvocationTargetException) ex).getTargetException();
					rethrowAnnotationConfigurationException(targetException);
				}
				throw new IllegalStateException("Could not obtain annotation attribute value for " + method, ex);
			}
		}

		return attributes;
	}

}
复制代码

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

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

主流程

源码分析

public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor, PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {

    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
		List<BeanDefinitionHolder> configCandidates = new ArrayList<BeanDefinitionHolder>();
		String[] candidateNames = registry.getBeanDefinitionNames();

        // 遍历beanfactory中全部已注册的bean
		for (String beanName : candidateNames) {
			BeanDefinition beanDef = registry.getBeanDefinition(beanName);
            // 判断是否为处理过的full配置类
			if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
                    // 判断是否为处理过的lite配置类
					ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
				if (logger.isDebugEnabled()) {
					logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
				}
			}
            // 判断是否为配置类(标注了@Configuration、@Component、@ComponentScan、@Import、@ImportResource)
            // 为full配置类时,为beanDef增长键为org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass,值为full的attribute
            // 为lite配置类时,为beanDef增长键为org.springframework.context.annotation.ConfigurationClassPostProcessor.configurationClass,值为lite的attribute
			else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
				configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
			}
		}

		// Return immediately if no @Configuration classes were found
		if (configCandidates.isEmpty()) {
			return;
		}

		// Sort by previously determined @Order value, if applicable
        // 配置类能够按照顺序加载
		Collections.sort(configCandidates, new Comparator<BeanDefinitionHolder>() {
			@Override
			public int compare(BeanDefinitionHolder bd1, BeanDefinitionHolder bd2) {
				int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
				int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
				return (i1 < i2) ? -1 : (i1 > i2) ? 1 : 0;
			}
		});

		// Detect any custom bean name generation strategy supplied through the enclosing application context
		SingletonBeanRegistry sbr = null;
		if (registry instanceof SingletonBeanRegistry) {
			sbr = (SingletonBeanRegistry) registry;
			if (!this.localBeanNameGeneratorSet && sbr.containsSingleton(CONFIGURATION_BEAN_NAME_GENERATOR)) {
				BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
				this.componentScanBeanNameGenerator = generator;
				this.importBeanNameGenerator = generator;
			}
		}

		// Parse each @Configuration class
		ConfigurationClassParser parser = new ConfigurationClassParser(
				this.metadataReaderFactory, this.problemReporter, this.environment,
				this.resourceLoader, this.componentScanBeanNameGenerator, registry);

		Set<BeanDefinitionHolder> candidates = new LinkedHashSet<BeanDefinitionHolder>(configCandidates);
		Set<ConfigurationClass> alreadyParsed = new HashSet<ConfigurationClass>(configCandidates.size());
		do {
            // 解析配置类,完成这一步流程后,在其内部对各类配置信息,包装为一个ConfigurationClass的集合
            // 在加载bean的过程当中,实际上也是对这个集合进行各类操做,如:从@Bean方法加载bean、@Import导入配置等等
			parser.parse(candidates);
			parser.validate();

			Set<ConfigurationClass> configClasses = new LinkedHashSet<ConfigurationClass>(parser.getConfigurationClasses());
			configClasses.removeAll(alreadyParsed);

			// Read the model and create bean definitions based on its content
			if (this.reader == null) {
				this.reader = new ConfigurationClassBeanDefinitionReader(
						registry, this.sourceExtractor, this.resourceLoader, this.environment,
						this.importBeanNameGenerator, parser.getImportRegistry());
			}
            // 对ConfigurationClassParser持有的配置信息集合进行bean的加载。
            // 至此,须要注册到IOC容器的全部bean都已注册完毕
			this.reader.loadBeanDefinitions(configClasses);
			alreadyParsed.addAll(configClasses);

			candidates.clear();
			if (registry.getBeanDefinitionCount() > candidateNames.length) {
				String[] newCandidateNames = registry.getBeanDefinitionNames();
				Set<String> oldCandidateNames = new HashSet<String>(Arrays.asList(candidateNames));
				Set<String> alreadyParsedClasses = new HashSet<String>();
				for (ConfigurationClass configurationClass : alreadyParsed) {
					alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
				}
				for (String candidateName : newCandidateNames) {
					if (!oldCandidateNames.contains(candidateName)) {
						BeanDefinition bd = registry.getBeanDefinition(candidateName);
						if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
								!alreadyParsedClasses.contains(bd.getBeanClassName())) {
							candidates.add(new BeanDefinitionHolder(bd, candidateName));
						}
					}
				}
				candidateNames = newCandidateNames;
			}
		}
		while (!candidates.isEmpty());

		// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
		if (sbr != null) {
			if (!sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
				sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
			}
		}

		if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
			((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
		}
	}

}
复制代码
相关文章
相关标签/搜索