AnnotationConfigApplicationContext bean注册
一、AnnotationConfigApplicationContext 初始化reader、scanner,设置扫描路径
二、ClassPathBeanDefinitionScanner负责根据扫描路径执行doScan(packages)扫描资源,并通过includeFilters和excludeFilters过滤后返回目标beanDefintion
三、ClassPathBeanDefinitionScanner调用registerBeanDefinition(definitionHolder, this.registry)将bean注册进注册器。
- AnnotationConfigApplicationContext("com.jty.spring.annotation")
public AnnotationConfigApplicationContext(String... basePackages) {
//调用无参构造方法
this();
//组件扫描
scan(basePackages);
refresh();
}
# this()初始化reader、scanner
public AnnotationConfigApplicationContext() {
this.reader = new AnnotatedBeanDefinitionReader(this);
//this(registry, true);使用默认includeFilters(AnnotationTypeFilter注解类型过滤器,且注解类型为Component)
//初始化metadataReaderFactory=CachingMetadataReaderFactory,该元数据阅读器工厂返回元数据阅读器为SimpleMetadataReader,
//后面用来从Resource中读取元数据信息,即类定义信息
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
- AnnotationConfigApplicationContext.scan(basePackages);#调用scanner.scan(basePackages);
- ClassPathBeanDefinitionScanner.scan(basePackages)
public int scan(String... basePackages) {
//统计未扫描前容器中BeanDefinition数目
int beanCountAtScanStart = this.registry.getBeanDefinitionCount();
//执行扫描操作
doScan(basePackages);
// Register annotation config processors, if necessary.
if (this.includeAnnotationConfig) {
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
//返回本次扫描注册的bean数目
return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}
- ClassPathBeanDefinitionScanner.doScan(basePackages)
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//用来保存BeanDefinitionHolder,该类用来包装BeanDefinition,还包括beanName、aliases属性
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
//组件扫描,返回候选bean定义
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) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
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;
}
- ClassPathScanningCandidateComponentProvider.findCandidateComponents(basePackage)
#ClassPathBeanDefinitionScanner继承ClassPathScanningCandidateComponentProvider
#ClassPathScanningCandidateComponentProvider通过类路径扫描或CandidateComponentsIndex查找候选者组件,
#通过includeFilters包含过滤器和excludeFilters排除过滤器选则出目标候选者
#如AnnotationTypeFilter用来过滤注解,通过注解类型
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
return scanCandidateComponents(basePackage);
}
}
- ClassPathScanningCandidateComponentProvider.scanCandidateComponents(basePackage)
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
//解析扫描路径即扫描文件类型,如classpath*:com/jty/spring/annotation/**/*.class
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//AbstractApplicationContext默认的创建PathMatchingResourcePatternResolver对象作为资源解析器
// 使用资源解析器解析PathMatchingResourcePatternResolver文件返回Resource类型对象。即将.class文件以Resource返回
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 {
//通过元数据阅读器从每个.class资源中读取元数据信息,即类定义的信息
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
if (isCandidateComponent(metadataReader)) {
/*
public ScannedGenericBeanDefinition(MetadataReader metadataReader) {
Assert.notNull(metadataReader, "MetadataReader must not be null");
//元信息
this.metadata = metadataReader.getAnnotationMetadata();
//类名
setBeanClassName(this.metadata.getClassName());
}
*/
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);
}
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;
}
PathMatchingResourcePatternResolver.getResources(packageSearchPath)
public Resource[] getResources(String locationPattern) throws IOException {
Assert.notNull(locationPattern, "Location pattern must not be null");
//如果以classpath*:开头
if (locationPattern.startsWith(CLASSPATH_ALL_URL_PREFIX)) {
// a class path resource (multiple resources for same name possible)
//一个类路径资源(可能有多个名称相同的资源)
//classpath*:后路径包含‘*’、‘?’、‘{}’则执行这步。
//具体怎么获取,可查看PathMatchingResourcePatternResolver.findPathMatchingResources(String locationPattern)
if (getPathMatcher().isPattern(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()))) {
// a class path resource pattern
//返回匹配路径的所有资源
return findPathMatchingResources(locationPattern);
}
else {
//否则执行,通过ClassLoader查找具有给定位置的所有类位置资源
// all class path resources with the given name
return findAllClassPathResources(locationPattern.substring(CLASSPATH_ALL_URL_PREFIX.length()));
}
}
else {
// Generally only look for a pattern after a prefix here,
// and on Tomcat only after the "*/" separator for its "war:" protocol.
int prefixEnd = (locationPattern.startsWith("war:") ? locationPattern.indexOf("*/") + 1 :
locationPattern.indexOf(':') + 1);
if (getPathMatcher().isPattern(locationPattern.substring(prefixEnd))) {
// a file pattern
return findPathMatchingResources(locationPattern);
}
else {
// a single resource with the given name
return new Resource[] {getResourceLoader().getResource(locationPattern)};
}
}
}
- ClassPathScanningCandidateComponentProvider.isCandidateComponent(sbd) #判断BeanDefinition是否时符合需求,即是否满足includeFilters包含过滤器和excludeFilters排除过滤器
protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException {
for (TypeFilter tf : this.excludeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return false;
}
}
for (TypeFilter tf : this.includeFilters) {
if (tf.match(metadataReader, getMetadataReaderFactory())) {
return isConditionMatch(metadataReader);
}
}
return false;
}
- 返回ClassPathBeanDefinitionScanner.doScan(basePackages)
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//用来保存BeanDefinitionHolder,该类用来包装BeanDefinition,还包括beanName、aliases属性
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
//组件扫描,返回候选bean定义,到这扫描步骤已经结束
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
//设置作用域,BeanDefinition中默认为单例singleton
candidate.setScope(scopeMetadata.getScopeName());
//默认使用类名简称shortClassName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//抽象类定义
if (candidate instanceof AbstractBeanDefinition) {
//设置bean默认属性
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
//接口定义
if (candidate instanceof AnnotatedBeanDefinition) {
//处理通用注释@Lazy、@Primary、@DependsOn、@Role、@Description
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//检查容器中是否存在该定义
if (checkCandidate(beanName, candidate)) {
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
//申请bean代理,若需要代理的话,将一个同该bean一样的代理bean注册
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//注册该beanDefintion
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
- ClassPathBeanDefinitionScanner.postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName)
protected void postProcessBeanDefinition(AbstractBeanDefinition beanDefinition, String beanName) {
//bean默认设置具体可查看BeanDefinitionDefaults.java
beanDefinition.applyDefaults(this.beanDefinitionDefaults);
if (this.autowireCandidatePatterns != null) {
//连接到bean定义中自动注入的属性
beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
}
}
- ClassPathBeanDefinitionScanner.registerBeanDefinition(definitionHolder, this.registry)
protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry) {
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}
- BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry)
public static void registerBeanDefinition(
BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
throws BeanDefinitionStoreException {
// Register bean definition under primary name.
String beanName = definitionHolder.getBeanName();
registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());
// Register aliases for bean name, if any.
String[] aliases = definitionHolder.getAliases();
if (aliases != null) {
for (String alias : aliases) {
registry.registerAlias(beanName, alias);
}
}
}
- GenericApplicationContext.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition())
//AnnotationConfigApplicationContext 继承GenericApplicationContext
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
//DefaultListableBeanFactory 即为注册器又是beanFactory,将BeanDefinition添加到beanDefinitionMap,
//this.beanDefinitionMap.put(beanName, beanDefinition);
//bean注册结束
this.beanFactory.registerBeanDefinition(beanName, beanDefinition);
}