Spring生命周期 (1)扫描类文件生成bean定义
bean的生命周期简略来看可以分为实例化前、实例化、实例化后、初始化前、初始化、初始化后。
详细来看可以是
- 扫描类文件生成bean定义
- 合并beandefinion
- 实例化前
- 推断构造方法
- 实例化
- beandefinition后置处理
- 填充属性
- 执行aware
- 初始化前
- 初始化
- 初始化后
接下来从源码挨个解析该过程
1 扫描扫描类文件生成bean定义
1 传递扫描包,根据扫描路径把对应的bean定义保存到map中
public int scan(String... basePackages) {
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
1.1 获取bean定义的数量
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
1.2 开始扫描 也就是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);
candidate.setScope(scopeMetadata.getScopeName());
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
if (candidate instanceof AnnotatedBeanDefinition) {
// 解析@Lazy、@Primary、@DependsOn、@Role、@Description
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查Spring容器中是否已经存在该beanName
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注册
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
public class BeanDefinitionHolder implements BeanMetadataElement {
private final BeanDefinition beanDefinition;
private final String beanName;
@Nullable
private final String[] aliases;
}
然后开始循环遍历给的路径,每个路径经过的方法是一样的,首先
Set candidates = findCandidateComponents(basePackage);这个方法的作用是扫描这些路径下的类,然后判断是否能转化成bean定义
1.3 scanCandidateComponents方法
findCandidateComponents然后会调用scanCandidateComponents(basePackage);这个方法,这个方法就是扫描的主要逻辑
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
// 获取basePackage下所有的文件资源
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//Spring的方法 可以把class文件转化成资源
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 {
//使用了asm框架读取class的元数据
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
// excludeFilters、includeFilters判断
if (isCandidateComponent(metadataReader)) { // @Component-->includeFilters判断
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
candidates.add(sbd);
} else {
if (debugEnabled) {
logger.debug("Ignored because not a concrete top-level class: " + resource);
}
}
} else {
if (traceEnabled) {
logger.trace("Ignored because not matching any filter: " + resource);
}
}
} catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to read candidate component class: " + resource, ex);
}
} else {
if (traceEnabled) {
logger.trace("Ignored because not readable: " + resource);
}
}
}
} catch (IOException ex) {
throw new BeanDefinitionStoreException("I/O failure during classpath scanning", ex);
}
return candidates;
}
isCandidateComponent(metadataReader)方法会把需要排除的类和需要添加的类装进两个List里面也就是
private final List<TypeFilter> includeFilters = new ArrayList<>();
private final List<TypeFilter> excludeFilters = new ArrayList<>();
excludeFilters是排除,当在这个里面的时候就算类可以创建成bean也不进行转化,可以在ComponentScan中添加排除一部分类。includeFilters是进行添加的 其中@Component就是在这个里面判断的。
其中 判断是否符合includeFilters之后进行了一个isConditionMatch(metadataReader);的方法,这个方法其实就是@Conditional注解的判断,也就是说这块先进行判断如果在excludeFilters里面直接返回false,然后不进行创建bean定义,再判断是否有includeFilters的注解啥的,如果有再进行判断Conditional注解,相关源码
匹配的源码 ,其中Conditional注解在isConditionMatch(metadataReader);中。
/**
* 确定给定类是否与任何排除筛选器匹配,而与至少一个包含筛选器匹配.
*
* @param metadataReader the ASM ClassReader for the class
* @return whether the class qualifies as a candidate component
*/
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
// 符合includeFilters的会进行条件匹配,通过了才是Bean,也就是先看有没有@Component,再看是否符合@Conditional
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
return false;
}
isConditionMatch方法接下来的调用
/**
*根据任何{@code @Conditional}注释确定给定的类是否是候选组件。
*
* @param metadataReader the ASM ClassReader for the class
* @return whether the class qualifies as a candidate component
*/
private boolean isConditionMatch(MetadataReader metadataReader) {
if (this.conditionEvaluator == null) {
this.conditionEvaluator =
new ConditionEvaluator(getRegistry(), this.environment, this.resourcePatternResolver);
}
return !this.conditionEvaluator.shouldSkip(metadataReader.getAnnotationMetadata());
}
shouldSkip的调用
/**
* 根据{@code @Conditional}注释确定一个项目是否应该被跳过。
* @param metadata the meta data
* @param phase the phase of the call
* @return if the item should be skipped
*/
public boolean shouldSkip(@Nullable AnnotatedTypeMetadata metadata, @Nullable ConfigurationPhase phase) {
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();
}
//condition的匹配方法
if ((requiredPhase == null || requiredPhase == phase) && !condition.matches(this.context, metadata)) {
return true;
}
}
return false;
}
我理解的这个方法的大概意义在于判断一个类是否要添加成一个bean定义,比如判断是否是抽象类,抽象类的情况处理等。
接下来返回scanCandidateComponents方法,当判断完一个类是否能转化成bean定义之后,把元数据转化成一个bean定义,
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
如果这个bean定义是一个顶级类或者不是抽象类的判断 也是bean定义是否正常的判断。
protected boolean isCandidateComponent(AnnotatedBeanDefinition beanDefinition) {
AnnotationMetadata metadata = beanDefinition.getMetadata();
return (metadata.isIndependent() && (metadata.isConcrete() ||
(metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName()))));
}
如果正常 返回回去存储进set返回回去。
Set<BeanDefinition> candidates = new LinkedHashSet<>();
然后返回到doscan方法,获取到了bean定义。
循环bean定义的方法再次摘抄出来 ,一行一行解析。
for (BeanDefinition candidate : candidates) {
//转化成注解元数据,可以使用工具类直接获取
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
//推断beanname,判断bean名称应该是什么 注解中有按照注解 没有按照大小写生成。
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//如果bean定义是抽象的 则设置一些默认属性。
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
//解析各种注解,存入bean定义中
if (candidate instanceof AnnotatedBeanDefinition) {
// 解析@Lazy、@Primary、@DependsOn、@Role、@Description
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
// 检查Spring容器中是否已经存在该beanName
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
// 注册 其实是保存进一个map中。
registerBeanDefinition(definitionHolder, this.registry);
}
}
到此为止 扫描的过程结束。