本篇文章主要介紹如下幾個部分:java
以DefaultListableBeanFactory爲例梳理一下BeanFactory接口體系的細節 spring
在spring的容器接口體系中,咱們可使用原材料、工廠、生產線操做工人、最終產品的關係來類比BeanDefinition、BeanFactory、BeanRegistry、bean實例。 BeanRegistry提供能力將BeanDefinition註冊到BeanFactory中,BeanFactory經過其內部的生產線來生成bean實例app
以AnnotatedGenericBeanDefinition爲例梳理一下BeanDefinition接口實現類體系框架
Metadata元數據部分在其內部包裝了須要註冊到BeanFactory的類的信息ide
BeanDefinition做爲註冊到BeanFactory中的載體,在具體的實現類中,持有metadata實例。工具
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註解的解析器
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;
}
}
複製代碼
在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();
}
}
}
複製代碼