目录
1. ConfigurationClassPostProcessor扫描和注册BeanDefinition
2. 解析配置类 ConfigurationClassParser#parse
2.1 处理内部类ConfigurationClassParser#processMemberClasses
2.2 处理@PropertySource注解
2.3 ComponentScanAnnotationParser处理@ComponentScan注解
2.4 处理@Import注解
2.5 处理@ImportResource注解
2.6 处理方法上的@Bean注解
2.7 处理接口的中的default方法
2.8 处理@Import导入的DeferredImportSelector类
3. ConfigurationClassBeanDefinitionReader
3.1 TrackedConditionEvaluator
3.2 注册Import导入的BeanDefinition
3.3 加载@Bean注解的方法
3.4 加载@ImportResource导入的BeanDefinition
3.5 通过Import导入的ImportBeanDefinitionRegistrar加载BeanDefinition
1. ConfigurationClassPostProcessor扫描和注册BeanDefinition
在refreshContext()刷新应用上下文 invokeBeanFactoryPostProcessors方法中, 执行了BeanFactoryPostProcessor#postProcessBeanDefinitionRegistry方法, 其中就包含了ConfigurationClassPostProcessor
主要执行了3个步骤
- 首先处理手动注册的BeanDefinition
- 实例化ConfigurationClassParser, 递归扫描@Configuration, @ComponentScan, @Import等注解
- 实例化ConfigurationClassBeanDefinitionReader,递归读取并注册BeanDefinition
public class ConfigurationClassPostProcessor implements BeanDefinitionRegistryPostProcessor,
PriorityOrdered, ResourceLoaderAware, BeanClassLoaderAware, EnvironmentAware {
//bean定义扫描和注册
@Override
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
//this.registriesPostProcessed包含了registryId
//说明postProcessBeanDefinitionRegistry方法已经执行
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
//this.factoriesPostProcessed已经包含了registryId
//说明postProcessBeanFactory方法已经执行
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
//添加到this.registriesPostProcessed中
//标记已经被执行
this.registriesPostProcessed.add(registryId);
//处理bean定义
processConfigBeanDefinitions(registry);
}
//处理bean定义
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//首先处理手动注册的BeanDefinition
//获取手工注册的bean定义名称列表
String[] candidateNames = registry.getBeanDefinitionNames();
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(bean)) {
//beanDefinition是lite或者是full
//full指的是使用了Configuration注解
//lite指的是使用了Component, ComponentScan, Import, ImportResource注解
//或者方法包含了Bean注解
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//当前beanDefinition是一个配置类
//添加到configCandidates中
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
if (configCandidates.isEmpty()) {
//如果配置类为空,那么立即返回
return;
}
//@Order注解排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
//设置bean名称生成策略
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//ConfigurationClassParser只负责解析被注解的类
//并不进行BeanDefinition的注册
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//Configuration类名
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//已经解析过的ConfigurationClass
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
//解析, 维护到parser.configurationClasses中
parser.parse(candidates);
//验证
//类不可以为final类型, 必须可重写, static方法不处理
parser.validate();
//configClasses维护待处理的ConfigurationClasse
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// this.reader初始化为ConfigurationClassBeanDefinitionReader
//进行BeanDefinition的加载
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//加载BeanDefinition
this.reader.loadBeanDefinitions(configClasses);
//alreadyParsed维护已经解析完的class
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//说明在加载Configuration注解类的过程中,
//扫描到了Import注解, 引入了新的BeanDefinition
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
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())) {
//@Configuration注解的类
//没有被处理过
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
//candidates不为空, 说明处理@Configuration注解的类
//扫描到了@Import注解, 引入了新的@Configuration注解类
while (!candidates.isEmpty());
//将@Import引入的类列表注册为单例Bean
//这样可以支持Configuration注解的ImportAware的实现类
//在实例化Bean的时候, 可以将Import导入的类, 传递给Bean实例
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
//清空缓存
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
}
2. 解析配置类 ConfigurationClassParser#parse
ConfigurationClassParser#parse方法, 共执行了下面8步
- 处理@Component
- @PropertySources
- @ComponentScans注解的类
- @Import引入的配置类
- @ImportResource导入配置资源类
- 处理@Bean注解
- 处理接口的default方法
- 处理父类
class ConfigurationClassParser {
//解析
//最终都会执行processConfigurationClass方法
public void parse(Set<BeanDefinitionHolder> configCandidates) {
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
if (bd instanceof AnnotatedBeanDefinition) {
//AnnotatedBeanDefinition类型
//解析metadata
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
//AbstractBeanDefinition类型
//解析beanClass
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
//MetadataReader类型
//解析beanClassName
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
//处理@Import导入的DeferredImportSelectorHolder类
this.deferredImportSelectorHandler.process();
}
//处理@Configuration注解的class
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) {
return;
}
//判断是否已经被处理过
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
//已经被处理过了
if (configClass.isImported()) {
//configClass是被Import导入的
if (existingClass.isImported()) {
//将configClass的importedBy合并到existingClass的existingClass中
existingClass.mergeImportedBy(configClass);
}
return;
}
else {
//如果configClass不是被Import导入
//那么说明是一个显式的bean定义, 我们旧的移除掉
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
SourceClass sourceClass = asSourceClass(configClass);
do {
//递归扫描并处理父类, 以及其注解
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
//维护已经处理的类
this.configurationClasses.put(configClass, configClass);
}
//实际解析配置类的方法
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
//configClass使用了@Component注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
//递归处理内部类
processMemberClasses(configClass, sourceClass);
}
//处理@PropertySources注解
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), @PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
//this.environment是ConfigurableEnvironment实例, 才进行@PropertySources属性替换
processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// 处理configClass类的@ComponentScans,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) {
// 交付给ComponentScanAnnotationParser进行扫描
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
//获取来源Beanthis.reader.loadBeanDefinitions(configClasses)Definition
//OriginatingBeanDefinition由代理设置
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
//BeanDefinition中的类由@Configuration注解
//调用parse方法, 递归处理@Configuration注解的类
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
//处理configClass类的@Import注解
processImports(configClass, sourceClass, getImports(sourceClass), true);
//处理configClass类的@ImportResource注解
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
if (importResource != null) {
//获取ImportResource的属性
String[] resources = importResource.getStringArray("locations");
Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
for (String resource : resources) {
//处理导入的resource
String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
configClass.addImportedResource(resolvedResource, readerClass);
}
}
// 处理sourceClass中@Bean注解的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
//添加到configClass中
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
//处理接口中的default方法
processInterfaces(configClass, sourceClass);
// 如果有父类的话, 处理父类
if (sourceClass.getMetadata().hasSuperClass()) {
String superclass = sourceClass.getMetadata().getSuperClassName();
if (superclass != null && !superclass.startsWith("java") &&
!this.knownSuperclasses.containsKey(superclass)) {
this.knownSuperclasses.put(superclass, configClass);
//返回父类
//递归处理父类
return sourceClass.getSuperClass();
}
}
//没有父类, 处理结束
return null;
}
}
2.1 处理内部类ConfigurationClassParser#processMemberClasses
如果内部类是full或者lite配置类, 那么就调用processConfigurationClass方法, 递归处理内部类, 做内部类的处理过程中, 使用了importStack, 维护导入的类, 用于判断循环导入
class ConfigurationClassParser {
//处理sourceClass的内部类
private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
Collection<SourceClass> memberClasses = sourceClass.getMemberClasses();
//内部类不为空
if (!memberClasses.isEmpty()) {
List<SourceClass> candidates = new ArrayList<>(memberClasses.size());
for (SourceClass memberClass : memberClasses) {
//内部类是full或者lite配置类
//也就是使用了@Configuration,@Component或者包含了@Bean方法注解
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) {
//维护到candidates列表中
candidates.add(memberClass);
}
}
OrderComparator.sort(candidates);
for (SourceClass candidate : candidates) {
if (this.importStack.contains(configClass)) {
//importStack包含了configClass
//说明出现了循环导入
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
this.importStack.push(configClass);
try {
//调用processConfigurationClass方法, 递归处理内部类
processConfigurationClass(candidate.asConfigClass(configClass));
}
finally {
//处理完成之后
//将configClass弹出
this.importStack.pop();
}
}
}
}
}
}
2.2 处理@PropertySource注解
读取@PropertySource注解的各个属性, 解析locations指定的文件, 然后将属性维护到environment的propertySources中
class ConfigurationClassParser {
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
//获取属性
String name = propertySource.getString("name");
if (!StringUtils.hasLength(name)) {
name = null;
}
String encoding = propertySource.getString("encoding");
if (!StringUtils.hasLength(encoding)) {
encoding = null;
}
String[] locations = propertySource.getStringArray("value");
Assert.isTrue(locations.length > 0, "At least one @PropertySource(value) location is required");
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
//自定义PropertySourceFactory类
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
for (String location : locations) {
try {
//从配置的location中加载配置数据
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
Resource resource = this.resourceLoader.getResource(resolvedLocation);
//解析后的数据维护到environment的属性中
addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
}
catch (IllegalArgumentException | FileNotFoundException | UnknownHostException ex) {
if (ignoreResourceNotFound) {
if (logger.isInfoEnabled()) {
logger.info("Properties location [" + location + "] not resolvable: " + ex.getMessage());
}
}
else {
throw ex;
}
}
}
}
//将解析的PropertySource维护到environment的PropertySources中
private void addPropertySource(PropertySource<?> propertySource) {
String name = propertySource.getName();
MutablePropertySources propertySources = ((ConfigurableEnvironment) this.environment).getPropertySources();
if (this.propertySourceNames.contains(name)) {
//this.propertySourceNames包含了属性
//说明该属性已经被处理过了
//environment的PropertySources中也会有一个对应的propertySource
PropertySource<?> existing = propertySources.get(name);
if (existing != null) {
PropertySource<?> newSource = (propertySource instanceof ResourcePropertySource ?
((ResourcePropertySource) propertySource).withResourceName() : propertySource);
//CompositePropertySource组合propertySource的话, 可以维护多个
if (existing instanceof CompositePropertySource) {
//添加到CompositePropertySource列表的首部
((CompositePropertySource) existing).addFirstPropertySource(newSource);
}
else {
if (existing instanceof ResourcePropertySource) {
existing = ((ResourcePropertySource) existing).withResourceName();
}
//转化为组合PropertySource
CompositePropertySource composite = new CompositePropertySource(name);
composite.addPropertySource(newSource);
composite.addPropertySource(existing);
//将原有的替换
propertySources.replace(name, composite);
}
return;
}
}
if (this.propertySourceNames.isEmpty()) {
//添加到propertySources的末尾
propertySources.addLast(propertySource);
}
else {
//添加到上一个propertySource的前面
//顺序正好和propertySourceNames相反
String firstProcessed = this.propertySourceNames.get(this.propertySourceNames.size() - 1);
propertySources.addBefore(firstProcessed, propertySource);
}
//维护到propertySourceNames中
//表示已经被处理过了
this.propertySourceNames.add(name);
}
}
2.3 ComponentScanAnnotationParser处理@ComponentScan注解
@SpringBootApplication注解使用了@ComponentScan注解
ComponentScanAnnotationParser处理@ComponentScan注解中配置的各个属性, 然后赋值给ClassPathBeanDefinitionScanner实例, 最后调用ClassPathBeanDefinitionScanner#doScan方法扫描各个配置类
class ComponentScanAnnotationParser {
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
//ClassPathBeanDefinitionScanner负责扫描BeanDefi
//useDefaultFilters是否使用默认filters
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//自定义BeanNameGenerator bean名称生成器
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
//ScopedProxyMode 代理模式
//默认不使用代理
//INTERFACES 基于接口, 使用JDK动态代理
//TARGET_CLASS 基于类, 使用CGLIB代理
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
//scopedProxyMode是DEFAULT
//实例化AnnotationScopeMetadataResolver
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
//设置resourcePattern
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
//添加includeFilter
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
//添加excludeFilter
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
//配置了laayInit
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
//获取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);
}
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
if (basePackages.isEmpty()) {
//没有配置basePackages
//取出declaringClass的包名
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
//设置忽略自己
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
//扫描basePackages
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
}
ClassPathBeanDefinitionScanner#doScan扫描basePackages
- 调用父类ClassPathScanningCandidateComponentProvider#findCandidateComponents, 扫描basePackage下的所有注解类, - 调用AnnotationScopeMetadataResolver#resolveScopeMetadata处理@Scope注解, 然后生成bean名称
- 设置BeanDefinition @Autowired注解解析, byType或者byName
- 设置BeanDefinition通用的注解, Lazy,Primary,DependsOn,Role,Description
- 验证扫描的类, 验证通过, 注册BeanDefinitionHolder, 放入BeanDefinitionHolder中
- 最后返回BeanDefinitionHolder列表
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
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) {
//调用父类findCandidateComponents方法
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
//获取candidate BeanDefinition上的Scope注解元数据
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
//AnnotationBeanNameGenerator生成bean名称
//考虑到了cglib动态代理
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
//设置@Autowired注解解析 byType或者byName
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
//设置通用的注解
//Lazy,Primary,DependsOn,Role,Description
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) {
//放入BeanDefinitionHolder中
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//维护到beanDefinitions列表
beanDefinitions.add(definitionHolder);
//注册definitionHolder
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
}
ClassPathScanningCandidateComponentProvider#findCandidateComponents
扫描basePackage下的所有配置类,通过MetadataReader读取包中的.class字节码, MetadataReader使用了asm框架, 最后处理为一个ScannedGenericBeanDefinition
public class ClassPathScanningCandidateComponentProvider implements EnvironmentCapable, ResourceLoaderAware {
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
//处理META-INF/spring.components配置的Component
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
//扫描Component
return scanCandidateComponents(basePackage);
}
}
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
//获取包路径
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//包内的class文件读取为Resource列表
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
for (Resource resource : resources) {
//处理resource
if (resource.isReadable()) {
try {
//MetadataReader使用了asm框架处理字节码
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
//生成ScannedGenericBeanDefinition ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setResource(resource);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
//添加到candidates列表
candidates.add(sbd);
}
//...
return candidates;
}
}
2.4 处理@Import注解
@SpringBootApplication注解使用了@EnableAutoConfiguration注解
- EnableAutoConfiguration注解使用了@Import注解, 导入了AutoConfigurationImportSelector, 找做了两件事情
- 扫描META-INF/spring-autoconfigure-metadata.properties维护的自动配置组件
- 扫描META-INF/spring.factories中配置的EnableAutoConfiguration子类
- EnableAutoConfiguration使用了@AutoConfigurationPackage注解, 导入了AutoConfigurationPackages.Registrar, 注册了一个BasePackages类型的Bean
处理@Import注解导入的配置类, 流程如下:
- 如果Import导入的类是否为ImportSelector的子类, 使用反射构造导入类的一个实例selector, 先调用ParserStrategyUtils.invokeAwareMethods方法, 如果实现了Aware接口的话, set相应Aware的对象
如果selector是DeferredImportSelector子类, 那么会维护到deferredImportSelectorHandler.deferredImportSelectors列表中, 最后在parse方法最后, 调用deferredImportSelectorHandler.process()处理selector
selector不是DeferredImportSelector子类, 调用selector.selectImports方法, 获取配置类列表, 然后调用processImports方法, 递归处理导入的配置类
- 如果Import导入的类是ImportBeanDefinitionRegistrar的子类, 使用反射构造导入类的也实例registrar, 先调用ParserStrategyUtils.invokeAwareMethods方法, 如果实现了Aware接口的话, set相应Aware的对象
ImportBeanDefinitionRegistrar用于动态注册BeanDefinition
将registrar添加到configClass.importBeanDefinitionRegistrars列表中
- 如果Import导入的类不是ImportSelector的子类, 也不是ImportBeanDefinitionRegistrar的子类, 就当成一个配置类处理
调用processConfigurationClass方法, 递归处理导入的类
class ConfigurationClassParser {
//处理@Import注解
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
//通过getImports方法获取的class列表
//如果为空,立即返回
if (importCandidates.isEmpty()) {
return;
}
//判断是否循环Import
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
//维护到importStack中
this.importStack.push(configClass);
try {
for (SourceClass candidate : importCandidates) {
if (candidate.isAssignable(ImportSelector.class)) {
// ImportSelector子类
Class<?> candidateClass = candidate.loadClass();
//如果是Aware接口的实现类,那么传入相应的生命周期数据
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
if (selector instanceof DeferredImportSelector) {
//DeferredImportSelector子类
//维护到deferredImportSelectorHandler.deferredImportSelectors列表中
this.deferredImportSelectorHandler.handle(
configClass, (DeferredImportSelector) selector);
}
else {
//不是DeferredImportSelector的子类
//调用selector.selectImports方法, 取出导入的类名
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
//递归处理导入的类
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// ImportBeanDefinitionRegistrar子类
Class<?> candidateClass = candidate.loadClass();
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
//将registrar添加到configClass.importBeanDefinitionRegistrars列表中
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// 不是ImportSelector和ImportBeanDefinitionRegistrar子类, 处理为配置类
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//递归处理
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
finally {
this.importStack.pop();
}
}
}
//获取sourceClass配置的@Import注解
private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException {
Set<SourceClass> imports = new LinkedHashSet<>();
Set<SourceClass> visited = new LinkedHashSet<>();
collectImports(sourceClass, imports, visited);
return imports;
}
//收集sourceClass上@Import注解中导入的类
private void collectImports(SourceClass sourceClass, Set<SourceClass> imports, Set<SourceClass> visited)
throws IOException {
//sourceClass维护到visited列表
if (visited.add(sourceClass)) {
for (SourceClass annotation : sourceClass.getAnnotations()) {
String annName = annotation.getMetadata().getClassName();
if (!annName.startsWith("java") && !annName.equals(Import.class.getName())) {
//递归收集注解上的@Import注解
collectImports(annotation, imports, visited);
}
}
//获取@Impost注解的value对应的类
//维护到imports列表中
imports.addAll(sourceClass.getAnnotationAttributes(Import.class.getName(), "value"));
}
}
}
2.5 处理@ImportResource注解
读取xml文件配置, 维护到configClass.importedResources中, key为resource路径, value为对应的reader
2.6 处理方法上的@Bean注解
遍历sourceClass中@Bean注解的方法, 然后维护到configClass.beanMethods中
class ConfigurationClassParser {
//遍历@Bean注解的方法
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
AnnotationMetadata original = sourceClass.getMetadata();
//获取@Bean注解的方法
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
try {
//尝试使用ASM框架读取字节码
AnnotationMetadata asm =
this.metadataReaderFactory.getMetadataReader(original.getClassName()).getAnnotationMetadata();
Set<MethodMetadata> asmMethods = asm.getAnnotatedMethods(Bean.class.getName());
if (asmMethods.size() >= beanMethods.size()) {
Set<MethodMetadata> selectedMethods = new LinkedHashSet<>(asmMethods.size());
for (MethodMetadata asmMethod : asmMethods) {
//ASM框架读取的方法顺序和JVM加载方法顺序不同, 所以使用了双重for循环
for (MethodMetadata beanMethod : beanMethods) {
if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
//维护到selectedMethods列表中
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
beanMethods = selectedMethods;
}
}
}
}
return beanMethods;
}
}
2.7 处理接口的中的default方法
遍历接口的方法, 如果方法不是abstract方法, 那么维护到configClass.beanMethods中
class ConfigurationClassParser {
private void processInterfaces(ConfigurationClass configClass, SourceClass sourceClass) throws IOException {
for (SourceClass ifc : sourceClass.getInterfaces()) {
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(ifc);
for (MethodMetadata methodMetadata : beanMethods) {
if (!methodMetadata.isAbstract()) {
//接口中的非抽象方法
//添加到configClass.beanMethods中
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
}
processInterfaces(configClass, ifc);
}
}
}
2.8 处理@Import导入的DeferredImportSelector类
ConfigurationClassParser.parse()方法最后调用了DeferredImportSelectorHandler#process()方法, 用来处理@Import注解导入的DeferredImportSelector类
class ConfigurationClassParser {
//私有内部类DeferredImportSelectorHandler
private class DeferredImportSelectorHandler {
public void process() {
List<DeferredImportSelectorHolder> deferredImports = this.deferredImportSelectors;
//每次调用都先重置
this.deferredImportSelectors = null;
try {
if (deferredImports != null) {
DeferredImportSelectorGroupingHandler handler = new DeferredImportSelectorGroupingHandler();
deferredImports.sort(DEFERRED_IMPORT_COMPARATOR);
//调用DeferredImportSelectorGroupingHandler#register方法
//
deferredImports.forEach(handler::register);
handler.processGroupImports();
}
}
finally {
this.deferredImportSelectors = new ArrayList<>();
}
}
}
private class DeferredImportSelectorGroupingHandler {
private final Map<Object, DeferredImportSelectorGrouping> groupings = new LinkedHashMap<>();
private final Map<AnnotationMetadata, ConfigurationClass> configurationClasses = new HashMap<>();
public void register(DeferredImportSelectorHolder deferredImport) {
//获取importSelector的group
Class<? extends Group> group = deferredImport.getImportSelector()
.getImportGroup();
//实例化一个DeferredImportSelectorGrouping
DeferredImportSelectorGrouping grouping = this.groupings.computeIfAbsent(
(group != null ? group : deferredImport),
key -> new DeferredImportSelectorGrouping(createGroup(group)));
grouping.add(deferredImport);
this.configurationClasses.put(deferredImport.getConfigurationClass().getMetadata(),
deferredImport.getConfigurationClass());
}
//使用group处理import
public void processGroupImports() {
for (DeferredImportSelectorGrouping grouping : this.groupings.values()) {
//grouping.getImports()获取了Import导入的类
grouping.getImports().forEach(entry -> {
ConfigurationClass configurationClass = this.configurationClasses.get(
entry.getMetadata());
try {
//调用processImports方法, 递归处理Import导入的类
processImports(configurationClass, asSourceClass(configurationClass),
asSourceClasses(entry.getImportClassName()), false);
}
//...
}
}
3. ConfigurationClassBeanDefinitionReader
BeanDefinition读取器
class ConfigurationClassBeanDefinitionReader {
//加载ConfigurationClass集合对应的BeanDefinition
public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
//TrackedConditionEvaluator用于处理@Conditional注解, 记录结果, 同时传入到@Import导入的类中
TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
for (ConfigurationClass configClass : configurationModel) {
//加载ConfigClass对应的BeanDefinition
loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator);
}
}
//加载ConfigurationClass对应的BeanDefinition列表
private void loadBeanDefinitionsForConfigurationClass(
ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) {
if (trackedConditionEvaluator.shouldSkip(configClass)) {
//@Conditional跳过当前Bean加载
String beanName = configClass.getBeanName();
if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
//如果BeanDefinition已经被加载过
//移除
this.registry.removeBeanDefinition(beanName);
}
//移除@Import注解导入的BeanDefinition
this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
return;
}
if (configClass.isImported()) {
//注册@Import导入的ConfigurationClass对应的BeanDefinition
registerBeanDefinitionForImportedConfigurationClass(configClass);
}
for (BeanMethod beanMethod : configClass.getBeanMethods()) {
//注册@Bean注解的方法对应的BeanDefinition
loadBeanDefinitionsForBeanMethod(beanMethod);
}
//注册@ImportResource对应的BeanDefinition
loadBeanDefinitionsFromImportedResources(configClass.getImportedResources());
//通过Import导入的ImportBeanDefinitionRegistrar加载BeanDefinition
loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars());
}
}
3.1 TrackedConditionEvaluator
扩展了ConditionEvaluator的能力, 记录了被忽略的ConfigurationClass, 并判断了导入类是否被忽略,
class ConfigurationClassBeanDefinitionReader {
private class TrackedConditionEvaluator {
//记录ConfigurationClass类的评估结果
private final Map<ConfigurationClass, Boolean> skipped = new HashMap<>();
public boolean shouldSkip(ConfigurationClass configClass) {
Boolean skip = this.skipped.get(configClass);
//没有被评估过
if (skip == null) {
if (configClass.isImported()) {
//导入类
boolean allSkipped = true;
for (ConfigurationClass importedBy : configClass.getImportedBy()) {
if (!shouldSkip(importedBy)) {
//所有的都跳过
allSkipped = false;
break;
}
}
if (allSkipped) {
skip = true;
}
}
if (skip == null) {
//使用conditionEvaluator进行评估
skip = conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN);
}
//skipped记录结果
this.skipped.put(configClass, skip);
}
return skip;
}
}
}
ConditionEvaluator
条件评估器, 最终调用Condition接口matches, 进行条件评估
class ConditionEvaluator {
private final ConditionContextImpl context;
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
//没有使用Conditional注解
//那么不跳过
if (metadata == null || !metadata.isAnnotated(Conditional.class.getName())) {
return false;
}
if (phase == null) {
//phase为null
if (metadata instanceof AnnotationMetadata &&
ConfigurationClassUtils.isConfigurationCandidate((AnnotationMetadata) metadata)) {
//@Configuration注解类
return shouldSkip(metadata, ConfigurationPhase.PARSE_CONFIGURATION);
}
return shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN);
}
List<Condition> conditions = new ArrayList<>();
//取出@Conditional注解value中设置的class名称列表
for (String[] conditionClasses : getConditionClasses(metadata)) {
for (String conditionClass : conditionClasses) {
//反射实例化对象
//维护到conditions列表
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();
}
//phase符合requiredPhase
//并调用condition.matches(this.context, metadata)进行验证
if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
return true;
}
}
return false;
}
}
SpringBootCondition
Spring封装的抽象类, 规定了matches方法要实现的一些模板方法, 用于打印日志和记录结果
public abstract class SpringBootCondition implements Condition {
@Override
public final boolean matches(ConditionContext context,
AnnotatedTypeMetadata metadata) {
String classOrMethodName = getClassOrMethodName(metadata);
try {
ConditionOutcome outcome = getMatchOutcome(context, metadata);
//打印日志
logOutcome(classOrMethodName, outcome);
//记录评估结果
recordEvaluation(context, classOrMethodName, outcome);
//返回outcome.match
return outcome.isMatch();
}
//...
}
//抽象方法
//ConditionOutcome记录了评估结果和消息
public abstract ConditionOutcome getMatchOutcome(ConditionContext context,
AnnotatedTypeMetadata metadata);
}
3.2 注册Import导入的BeanDefinition
先获取configClass的AnnotationMetadata, 然后取出Scope注解, 如果Scope不是DEFAULT或者NO的话, 会生成一个ScopedProxyFactoryBean类型的BeanDefinition, 放入BeanDefinitionHolder中
class ConfigurationClassBeanDefinitionReader {
private void registerBeanDefinitionForImportedConfigurationClass(ConfigurationClass configClass) {
AnnotationMetadata metadata = configClass.getMetadata();
AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
//取得Scope注解
ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
configBeanDef.setScope(scopeMetadata.getScopeName());
//生成bean名称
String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
//处理通用注解
AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
//如果Scope不是DEFAULT或者NO
//那么就通过ScopedProxyUtils#createScopedProxy生成一个ScopedProxyFactoryBean类型的BeanDefinition
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
configClass.setBeanName(configBeanName);
if (logger.isTraceEnabled()) {
logger.trace("Registered bean definition for imported class '" + configBeanName + "'");
}
}
}
3.3 加载@Bean注解的方法
class ConfigurationClassBeanDefinitionReader {
private void loadBeanDefinitionsForBeanMethod(BeanMethod beanMethod) {
ConfigurationClass configClass = beanMethod.getConfigurationClass();
MethodMetadata metadata = beanMethod.getMetadata();
String methodName = metadata.getMethodName();
// 判断是否要跳过
if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
configClass.skippedBeanMethods.add(methodName);
return;
}
if (configClass.skippedBeanMethods.contains(methodName)) {
return;
}
AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
Assert.state(bean != null, "No @Bean annotation attributes");
//获取@Bean的name属性
List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
// 注册alias
for (String alias : names) {
this.registry.registerAlias(beanName, alias);
}
// 是否被重写
if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription(),
beanName, "Bean name derived from @Bean method '" + beanMethod.getMetadata().getMethodName() +
"' clashes with bean name for containing configuration class; please make those names unique!");
}
return;
}
ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
beanDef.setResource(configClass.getResource());
beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
if (metadata.isStatic()) {
//处理static方法
beanDef.setBeanClassName(configClass.getMetadata().getClassName());
beanDef.setFactoryMethodName(methodName);
}
else {
//处理普通方法
beanDef.setFactoryBeanName(configClass.getBeanName());
//
beanDef.setUniqueFactoryMethodName(methodName);
}
//默认使用构造器实例化
beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
//
beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.
SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
//设置配置的autowire
Autowire autowire = bean.getEnum("autowire");
if (autowire.isAutowire()) {
beanDef.setAutowireMode(autowire.value());
}
boolean autowireCandidate = bean.getBoolean("autowireCandidate");
if (!autowireCandidate) {
beanDef.setAutowireCandidate(false);
}
//init方法
String initMethodName = bean.getString("initMethod");
if (StringUtils.hasText(initMethodName)) {
beanDef.setInitMethodName(initMethodName);
}
//destory方法
String destroyMethodName = bean.getString("destroyMethod");
beanDef.setDestroyMethodName(destroyMethodName);
//处理Scope注解
ScopedProxyMode proxyMode = ScopedProxyMode.NO;
AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
if (attributes != null) {
beanDef.setScope(attributes.getString("value"));
proxyMode = attributes.getEnum("proxyMode");
if (proxyMode == ScopedProxyMode.DEFAULT) {
proxyMode = ScopedProxyMode.NO;
}
}
//如果Scope不是DEFAULT和NO
//就通过ScopedProxyUtils#createScopedProxy生成一个ScopedProxyFactoryBean类型的BeanDefinition
BeanDefinition beanDefToRegister = beanDef;
if (proxyMode != ScopedProxyMode.NO) {
BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(
new BeanDefinitionHolder(beanDef, beanName), this.registry,
proxyMode == ScopedProxyMode.TARGET_CLASS);
beanDefToRegister = new ConfigurationClassBeanDefinition(
(RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
}
if (logger.isTraceEnabled()) {
logger.trace(String.format("Registering bean definition for @Bean method %s.%s()",
configClass.getMetadata().getClassName(), beanName));
}
//注册BeanDefinition
this.registry.registerBeanDefinition(beanName, beanDefToRegister);
}
}
3.4 加载@ImportResource导入的BeanDefinition
通过BeanDefinitionReader加载BeanDefinition
3.5 通过Import导入的ImportBeanDefinitionRegistrar加载BeanDefinition
通过执行的ImportBeanDefinitionRegistrar子类的registerBeanDefinitions方法, 加载BeanDefinition