spring-framework 版本:v5.3.19
注解方式(AnnotationConfigApplicationContext)
AnnotationConfigRegistry接口有两个方法,分别对应了注解生成beanDefinition的两种方式
来到其实现类AnnotationConfigApplicationContext可以发现类里有两个成员变量reader和scanner
reader对应register方法(根据传入class生成beanDefinition)
scanner对应scan方法(根据传入包名扫描特定注解表示的class生成beanDefinition)
先看register方法的实现
AnnotationConfigApplicationContext#register
AnnotatedBeanDefinitionReader#doRegisterBean
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//根据bean类生成beanDefinition(实际上就是解析出 AnnotationMetadata 元数据)
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
//根据condition注解条件判断是否跳过
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
//创建bean之后的回调方法
abd.setInstanceSupplier(supplier);
//设置作用域
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
//得到beanName
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//通用注解解析:Lazy、Primary、DependsOn、Role、Description
AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
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));
}
}
}
//自定义处理
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
//封装成BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
//是否需要代理
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//注册beanDefinition到registry
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
BeanDefinitionRegistry#registerBeanDefinition
进入BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry)方法
可以发现最终会调用BeanDefinitionRegistry.registerBeanDefinition方法。但这是一个接口,其对应的实现类是哪个呢?
其实就是AnnotationConfigApplicationContext本身。
在赋值reader的时候会把自身传进去赋值给register,而AnnotationConfigApplicationContext继承自GenericApplicationContext,GenericApplicationContext又继承自BeanDefinitionRegistry,所以AnnotationConfigApplicationContext也是一个BeanDefinitionRegistry。
GenericApplicationContext.registerBeanDefinition实际上只是调用了另一个实现类DefaultListableBeanFactory的registerBeanDefinition方法
reader赋值
GenericApplicationContext.registerBeanDefinition
综上最终会来到DefaultListableBeanFactory#registerBeanDefinition,也即BeanDefinitionRegistry#registerBeanDefinition
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
throws BeanDefinitionStoreException {
Assert.hasText(beanName, "Bean name must not be empty");
Assert.notNull(beanDefinition, "BeanDefinition must not be null");
//抽象beanDefinition的一些处理(beanDefinition也有继承关系)
if (beanDefinition instanceof AbstractBeanDefinition) {
try {
((AbstractBeanDefinition) beanDefinition).validate();
}
catch (BeanDefinitionValidationException ex) {
throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
"Validation of bean definition failed", ex);
}
}
//beanName是否已经存在beanDefinition
BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);
if (existingDefinition != null) {
//不允许覆盖则报错
if (!isAllowBeanDefinitionOverriding()) {
throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
}
//打印一些日志
else if (existingDefinition.getRole() < beanDefinition.getRole()) {
// e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
if (logger.isInfoEnabled()) {
logger.info("Overriding user-defined bean definition for bean '" + beanName +
"' with a framework-generated bean definition: replacing [" +
existingDefinition + "] with [" + beanDefinition + "]");
}
}
else if (!beanDefinition.equals(existingDefinition)) {
if (logger.isDebugEnabled()) {
logger.debug("Overriding bean definition for bean '" + beanName +
"' with a different definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
else {
if (logger.isTraceEnabled()) {
logger.trace("Overriding bean definition for bean '" + beanName +
"' with an equivalent definition: replacing [" + existingDefinition +
"] with [" + beanDefinition + "]");
}
}
//覆盖原beanDefinition
this.beanDefinitionMap.put(beanName, beanDefinition);
}
else {
//判断是否有bean开始注册了,有就加锁保证线程安全
if (hasBeanCreationStarted()) {
synchronized (this.beanDefinitionMap) {
this.beanDefinitionMap.put(beanName, beanDefinition);
List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
updatedDefinitions.addAll(this.beanDefinitionNames);
updatedDefinitions.add(beanName);
this.beanDefinitionNames = updatedDefinitions;
removeManualSingletonName(beanName);
}
}
//没有就直接注册beanDefinition
else {
this.beanDefinitionMap.put(beanName, beanDefinition);
this.beanDefinitionNames.add(beanName);
removeManualSingletonName(beanName);
}
this.frozenBeanDefinitionNames = null;
}
//如果存在过beanName对应的beanDefinition或者单例bean则重置beanDefinition
//移除合并的beanDefinition、销毁单例bean、执行MergedBeanDefinitionPostProcessor.resetBeanDefinition
if (existingDefinition != null || containsSingleton(beanName)) {
resetBeanDefinition(beanName);
}
//如果beanDefinition被冻结的一些处理
else if (isConfigurationFrozen()) {
clearByTypeCache();
}
}
至此beanDefinition就注册到容器上了。
接下来扫描包的方式即scan方法
AnnotationConfigApplicationContext#scan
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) {
//扫描生成BeanDefinition
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
for (BeanDefinition candidate : candidates) {
//得到作用域元数据
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
//设置作用域
candidate.setScope(scopeMetadata.getScopeName());
//得到beanName
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
//通用注解解析:Lazy、Primary、DependsOn、Role、Description
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//检测BeanDefinition的beanName是否与其他BeanDefinition存在冲突
//虽然是一个判断,当时会有三种情况:true:beanName没有冲突,false:有冲突但兼容,抛异常:有冲突且不兼容
if (checkCandidate(beanName, candidate)) {
//没有冲突则注册
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
beanDefinitions.add(definitionHolder);
//注册beanDefinition
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}]
findCandidateComponents
findCandidateComponents方法返回Set < BeanDefinition > 。可以发现当有指定spring.components文件时,会直接用该文件加快加载,否则扫描包下所有资源。
scanCandidateComponents
这里会先得到包下所有的Resource,再依次获取元数据封装到MetadataReader,当满足excludeFilter/includeFilter/condition条件时,创建ScannedGenericBeanDefinition。
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);
}
try {
//得到元数据
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
//判断excludeFilter/includeFilter/condition条件
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
//判断excludeFilter/includeFilter/condition条件
if (isCandidateComponent(sbd)) {
if (debugEnabled) {
logger.debug("Identified candidate component class: " + resource);
}
//添加扫描beanDefinition
candidates.add(sbd);
}
//以下都是日志异常处理......
isCandidateComponent
BeanDefinitionRegistry#registerBeanDefinition
进入registerBeanDefinition(definitionHolder, this.registry);
可以发现最后跟register一样调用BeanDefinitionReaderUtils#registerBeanDefinition进而调用BeanDefinitionRegistry#registerBeanDefinition,这里就不再说一遍了。
XML方式(AbstractXmlApplicationContext)
AbstractXmlApplicationContext#loadBeanDefinitions
AbstractXmlApplicationContext会调用BeanDefinitionReader#loadBeanDefinitions加载xml文件,而xml方式具体的实现类就是XmlBeanDefinitionReader。
虽然XmlBeanDefinitionReader和上面提到的AnnotatedBeanDefinitionReader都是以BeanDefinitionReader结尾,但是实际上这两个从类继承来看没有什么关系,并不来自于同一基类也不互相继承。XmlBeanDefinitionReader实现了BeanDefinitionReader接口,而AnnotatedBeanDefinitionReader不实现任何接口也不继承任何类。
跟踪XmlBeanDefinitionReader代码来到真正做事的地方:doLoadBeanDefinitions方法
XmlBeanDefinitionReader#doLoadBeanDefinitions
最终来到BeanDefinitionDocumentReader.doRegisterBeanDefinitions()方法
BeanDefinitionDocumentReader#doRegisterBeanDefinitions
这一步主要就是对各种标签的解析
BeanDefinitionRegistry#registerBeanDefinition
进入bean标签的解析
可以发现最后同样调用BeanDefinitionReaderUtils#registerBeanDefinition进而调用BeanDefinitionRegistry#registerBeanDefinition,剩下的步骤就跟注解方式的一样了。
总结
注解方式可register直接注册,也可scan扫描注册。register方式通过AnnotatedBeanDefinitionReader创建beanDefinition(同时会得到元数据),再根据元数据等设置完beanDefinition属性后,用BeanDefinitionRegistry注册到容器。scan方式通过ClassPathBeanDefinitionScanner先扫描生成所有的BeanDefinition(同时会得到元数据),依次遍历BeanDefinition,根据元数据等设置BeanDefinition的属性,最后检查是否冲突,当无冲突时也用BeanDefinitionRegistry注册到容器。
xml方式通过XmlBeanDefinitionReader先加载xml文件并封装成document,再将document委托给BeanDefinitionDocumentReader对各种标签进行解析生成beanDefinition,最后用BeanDefinitionRegistry注册到容器中。
可以发现无论是注解register还是注解scan还是xml最终在注册到容器时都会用到BeanDefinitionRegistry,而其具体的实现就是DefaultListableBeanFactory#registerBeanDefinition。