概述:根据扫描的前后顺序,分为两大类来看,第一类使用@Component,@PropertySource,@ComponentScans,@ComponentScan,@Import,@ImportResource,@Bean的类,若在扫描路径中,则会被扫描到,但只有组件类会获取其BeanDefinition,其他获取ConfigurationClass;第二类被自动配置的类,会先看缓存有没有,若没有则扫描对应的spring.factories来获取类,再当做@Configuration的类来处理,执行第一类也使用的processConfigurationClass方法,获取其ConfigurationClass。最后使用ConfigurationClassBeanDefinitionReader的loadBeanDefinitions方法来统一用ConfigurationClass生成BeanDefinition。接下来,挑选比较重要的部分,分析源码。
追踪代码:
文章目录
- 第一类:
- 1.ConfigurationClassParser.parse:
- 2.ConfigurationClassParser.processConfigurationClass:
- 3.ConfigurationClassParser.doProcessConfigurationClass:
- 3.1ComponentScanAnnotationParser.parse:
- 3.1.1 ClassPathBeanDefinitionScanner.doScan:
- 3.1.2 ClassPathScanningCandidateComponentProvider.scanCandidateComponents:
- 3.2 ConfigurationClassParser.processImports:
- 第二类:
- 用ConfigurationClass生成beanDefinition
- 注意:
第一类:
1.ConfigurationClassParser.parse:
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
//顺序处理使用@Component,@PropertySource,@ComponentScans,@ComponentScan,@Import,@ImportResource,@Bean的类
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
......
//处理自动配置的类
this.deferredImportSelectorHandler.process();
}
2.ConfigurationClassParser.processConfigurationClass:
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
......
do {
//准备生成beanDefinition
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
3.ConfigurationClassParser.doProcessConfigurationClass:
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
//处理@Component
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 递归处理内部类
processMemberClasses(configClass, sourceClass);
}
// Process any @PropertySource annotations
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 处理@ComponentScan
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
for (AnnotationAttributes componentScan : componentScans) {
//生成@ComponentScan扫描范围内的符合条件的组件类的BeanDefinitionHolder
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// 检查扫描的beandefinition,按需递归查找组件类
Check the set of scanned definitions for any further config classes and parse recursively if needed
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//如果是组件类,又要以该类为根查找符合条件的类
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 处理 @Import
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理 @ImportResource
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
//处理@Bean (这里只会解析注册到每个类的meta里面有哪些@Bean注释的方法)
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
......
// No superclass -> processing is complete
return null;
}
3.1ComponentScanAnnotationParser.parse:
生成scanner
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
//获取一个scanner,用于承包componentScan里面的属性信息
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//设置scanner的beanNameGenerator
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
//设置scanner的scopedProxyMode
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
//设置scanner的scopeMetadataResolver
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
//设置scanner的resourcePattern
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
//设置scanner的includeFilters
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
//设置scanner的excludeFilters
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
//设置scanner的lazyInit
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
//设置scanner的basePackages
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
//设置scanner的basePackageClasses
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
//如果没有设置任何扫描路径,就会默认扫描路径为添加@ComponentScan的类所在路径及其子包
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
//添加一个过滤器,预处理类不能和初始类(带有该@ComponentScan的类)相同
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
3.1.1 ClassPathBeanDefinitionScanner.doScan:
处理组件类
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
//获取扫描包下的所有组件类
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
//设置scope
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
//设置默认的一些信息,比如是否懒加载等
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//看类是否有primary,role,dependsOn等注解,有就设置相应属性为true
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//主要看是不是已经存在该beandefinition(否就返回true)(是就判断能不能覆盖后兼容)
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
//设置该类的代理模式
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//注册该类到registry的beandefinitionMap、beanDefinitionNames、manualSingletonNames
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
3.1.2 ClassPathScanningCandidateComponentProvider.scanCandidateComponents:
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
//生成路径
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//获取路径下所有类
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
//判断该类是不是组件类
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
}
......
}
catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
3.2 ConfigurationClassParser.processImports:
处理@Import
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// 如果是ImportSelector,为之实例化
Class<?> candidateClass = candidate.loadClass();
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
//如果是延迟的ImportSelector,进行处理或者添加在DeferredImportSelector里面等待处理
if (selector instanceof DeferredImportSelector) {
this.deferredImportSelectorHandler.handle(
configClass, (DeferredImportSelector) selector);
}
//否则递归处理
else {
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// 如果是ImportBeanDefinitionRegistrar 就为之添加ImportBeanDefinitionRegistrar
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// 当做@Configuration处理
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
......
finally {
this.importStack.pop();
}
}
}
第二类:
1.ConfigurationClassParser.parse:
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
......
}
//加载自动配置类到configurationclasses的入口
this.deferredImportSelectorHandler.process();
}
2.ConfigurationClassParser.process:
public void process() {
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
this.deferredImportSelectors = null;
try {
if (deferredImports != null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
deferredImports.forEach(handler::register);
//扫描spring.factories,获取里面的factoryclassname和相应的类,并且将自动配置类作为一个@Configuration的类加载,执行processConfigurationClass,添加自己到configurationclasses里面
handler.processGroupImports();
}
}
finally {
this.deferredImportSelectors = new ArrayList<>();
}
}
3.ConfigurationClassParser.processGroupImports:
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
//getImports会获取自动配置类
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(
entry.getMetadata());
try {
//每个自动配置类当成配置类处理
processImports(configurationClass, asSourceClass(configurationClass),
asSourceClasses(entry.getImportClassName()), false);
}
......
});
}
}
4.AutoConfigurationImportSelector.selectImports:
getImports最后会调用selectImports来为自动配置类排序(@AutoConfigureBefore/After)
public Iterable<Entry> selectImports() {
if (this.autoConfigurationEntries.isEmpty()) {
return Collections.emptyList();
}
Set<String> allExclusions = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getExclusions)
.flatMap(Collection::stream).collect(Collectors.toSet());
Set<String> processedConfigurations = this.autoConfigurationEntries.stream()
.map(AutoConfigurationEntry::getConfigurations)
.flatMap(Collection::stream)
.collect(Collectors.toCollection(LinkedHashSet::new));
processedConfigurations.removeAll(allExclusions);
return sortAutoConfigurations(processedConfigurations,
getAutoConfigurationMetadata())
.stream()
.map((importClassName) -> new Entry(
this.entries.get(importClassName), importClassName))
.collect(Collectors.toList());
}
辗转找到AutoConfigurationSorter的getInPriorityOrder方法来真正排序
public List<String> getInPriorityOrder(Collection<String> classNames) {
AutoConfigurationClasses classes = new AutoConfigurationClasses(
this.metadataReaderFactory, this.autoConfigurationMetadata, classNames);
List<String> orderedClassNames = new ArrayList<>(classNames);
// 根据字母排序
Collections.sort(orderedClassNames);
// 根据order排序
orderedClassNames.sort((o1, o2) -> {
int i1 = classes.get(o1).getOrder();
int i2 = classes.get(o2).getOrder();
return Integer.compare(i1, i2);
});
//处理@AutoConfigureBefore @AutoConfigureAfter
orderedClassNames = sortByAnnotation(classes, orderedClassNames);
return orderedClassNames;
}
5.ConfigurationClassParser.processImports:
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
if (importCandidates.isEmpty()) {
return;
}
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
.......
else {
// Candidate class not an ImportSelector or ImportBeanDefinitionRegistrar ->
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//当做 @Configuration class来处理
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
.......
finally {
this.importStack.pop();
}
}
}
用ConfigurationClass生成beanDefinition
ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass:
为ConfigurationClass加载beanDefinition(@Import,@Bean,自动配置类)
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
//如果是被import,根据importBy类来决定是否跳过,且是否符合conditional条件
if (trackedConditionEvaluator.shouldSkip(configClass)) {
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
this.registry.removeBeanDefinition(beanName);
}
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
//这个类是不是被其他的类import或者自动配置
if (configClass.isImported()) {
//根据ImportedConfigurationClass注册BeanDefinition
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
//该类的@Bean方法,在此注册bean
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
loadBeanDefinitionsForBeanMethod(beanMethod);
}
//根据ImportedResources加载注册BeanDefinition
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//根据ImportBeanDefinitionRegistrars加载注册BeanDefinition
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
ConditionEvaluator判断类是否满足条件,满足才能生成beanDefinition
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
//有没有@Conditional
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}
if (phase == null) {
if (metadata instanceof AnnotationMetadata &&
ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
}
return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
}
//获取所有条件
List<Condition> conditions = new ArrayList<>();
for (String[] conditionClasses : getConditionClasses(metadata)) {
for (String conditionClass : conditionClasses) {
Condition condition = getCondition(conditionClass, this.context.getClassLoader());
conditions.add(condition);
}
}
//排序
AnnotationAwareOrderComparator.sort(conditions);
//有不符合的条件就要跳过
for (Condition condition : conditions) {
ConfigurationPhase requiredPhase = null;
if (condition instanceof ConfigurationCondition) {
requiredPhase = ((ConfigurationCondition) condition).getConfigurationPhase();
}
if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
return true;
}
}
return false;
}
注意:
在整个过程中会牵扯到生成一个scanner来扫描类,会先扫描根路径再是其子路径的类(且先扫描大写字母的类,再扫描小写字母的类)。如果该类里面有着多种上述(@Import,@ComponentScan等)注解,则会依次(上面注解顺序)解析相应的类。