前言
这次写的内容,是接着上次的博客Spring从源码层面剖析——上
因为spring源码有几万行,即使只看核心代码,也要看很久,所以分两次来学习记录。
IOC
接着上次看Spring的IOC,看它是怎么创建bean对象。
根据上次debug看程序的执行流程,我们知道了spring已经把几个后置处理器类 ( xxxPostProcessor)和我们定义的配置类(MainConfig)注册成了bean定义(BeanDefinition)。 我们看到了核心方法 refresh(),然后进一步跟到了一个方法processConfigBeanDefinitions
processConfigBeanDefinitions
/**
* Build and validate a configuration model based on the registry of
* {@link Configuration} classes.
*/
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//获取IOC 容器中目前所有bean定义的名称
String[] candidateNames = registry.getBeanDefinitionNames();
//循环我们的上一步获取的所有的bean定义信息
for (String beanName : candidateNames) {
//通过bean的名称来获取我们的bean定义对象
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//判断是否有没有解析过
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//进行正在的解析判断是不是完全的配置类 还是一个非正式的配置类
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
//满足添加 就加入到候选的配置类集合中
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);
});
// 创建我们通过@CompentScan导入进来的bean name的生成器
// 创建我们通过@Import导入进来的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) {
//设置@CompentScan导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义,一般不会
this.componentScanBeanNameGenerator = generator;
//设置@Import导入进来的bean的名称生成器(默认类首字母小写)也可以自己定义,一般不会
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//创建一个配置类解析器对象
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//用于保存我们的配置类BeanDefinitionHolder放入上面筛选出来的配置类
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//用于保存我们的已经解析的配置类,长度默认为解析出来默认的配置类的集合长度
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
//do while 会进行第一次解析
do {
//真正的解析我们的配置类
parser.parse(candidates); //todo:(注意这个方法,后续我们要重点跟进)
parser.validate();
//解析出来的配置类
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
// Read the model and create bean definitions based on its content
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
// 此处才把@Bean的方法和@Import 注册到BeanDefinitionMap中
this.reader.loadBeanDefinitions(configClasses);
//加入到已经解析的集合中
alreadyParsed.addAll(configClasses);
candidates.clear();
//判断我们ioc容器中的是不是>候选原始的bean定义的个数
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//获取所有的bean定义
String[] newCandidateNames = registry.getBeanDefinitionNames();
//原始的老的候选的bean定义
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())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
//存在没有解析过的 需要循环解析
while (!candidates.isEmpty());
// Register the ImportRegistry as a bean in order to support ImportAware @Configuration classes
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
// Clear cache in externally provided MetadataReaderFactory; this is a no-op
// for a shared cache since it'll be cleared by the ApplicationContext.
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
跟进这个方法:parser.parse(candidates); 是去解析BeanDefinition。
public void parse(Set<BeanDefinitionHolder> configCandidates) {
/**
* 用于来保存延时的ImportSelectors,最最最著名的代表就是我们的SpringBoot自动装配的的类 AutoConfigurationImportSelector
*/
this.deferredImportSelectors = new LinkedList<>();
// 循环配置类
for (BeanDefinitionHolder holder : configCandidates) {
BeanDefinition bd = holder.getBeanDefinition();
try {
//真正的解析我们的bean定义 :通过注解元数据 解析
if (bd instanceof AnnotatedBeanDefinition) {
//todo:(注意这个方法,后续我们要重点跟进)
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) {
parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}
else {
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to parse configuration class [" + bd.getBeanClassName() + "]", ex);
}
}
//处理我们延时的DeferredImportSelectors w我们springboot就是通过这步进行记载spring.factories文件中的自定装配的对象
processDeferredImportSelectors();
}
接着跟进它解析的核心方法:parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
/**
* 真的解析我们的配置类
* @param metadata 配置类的源信息
* @param beanName 当前配置类的beanName
* @throws IOException
*/
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
/**
* 把我们的配置类源信息和beanName包装成一个ConfigurationClass 对象
*/
//todo:(注意这个方法,后续我们要重点跟进)
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
看到它执行了processConfigurationClass方法,继续跟进 processConfigurationClass
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) {
//传入进来的配置类是通过其他配置类的Import导入进来的
if (configClass.isImported()) {
if (existingClass.isImported()) {
//需要合并配置
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
// 所以假如通过@Import导入一个 已存在的配置类 是不允许的,会忽略。
return;
}
else {
// Explicit bean definition found, probably replacing an import.
// Let's remove the old one and go with the new one.
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// Recursively process the configuration class and its superclass hierarchy.递归处理配置类及其超类层次结构。
SourceClass sourceClass = asSourceClass(configClass);
//真正的进行配置类的解析
do {
//解析我们的配置类 //todo:(注意这个方法,后续我们要重点跟进)
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
this.configurationClasses.put(configClass, configClass);
}
这行代码 :sourceClass = doProcessConfigurationClass(configClass, sourceClass);
通过经验总结在spring源码中,如果一个方法是do开头的,那这个方法会特别重要,是真正做事的核心方法,那我们重点寻找的核心代码也将会在这个方法里体现。
下面继续跟进 doProcessConfigurationClass方法
重要方法 doProcessConfigurationClass
/**
* Apply processing and build a complete {@link ConfigurationClass} by reading the
* annotations, members and methods from the source class. This method can be called
* multiple times as relevant sources are discovered.
* @param configClass the configuration class being build
* @param sourceClass a source class
* @return the superclass, or {@code null} if none found or previously processed
*/
@Nullable
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
// Recursively process any member (nested) classes first
processMemberClasses(configClass, sourceClass);
//处理我们的@propertySource注解的
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
processPropertySource(propertySource);
}
else {
logger.warn("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
//解析我们的 @ComponentScan 注解
//从我们的配置类上解析处ComponentScans的对象集合属性
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
//循环解析 我们解析出来的AnnotationAttributes
for (AnnotationAttributes componentScan : componentScans) {
//把我们扫描出来的类变为bean定义的集合 真正的解析 //todo:(注意这个方法,后续我们要重点跟进)
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
//循环处理我们包扫描出来的bean定义
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//判断当前扫描出来的bean定义是不是一个配置类,若是的话 直接进行递归解析
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
//递归解析 因为@Component算是lite配置类
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// 处理 @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), true);
// 处理 @ImportResource annotations
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 methods 获取到我们配置类中所有标注了@Bean的方法
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// 处理配置类接口 默认方法的@Bean
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);
// Superclass found, return its annotation metadata and recurse
return sourceClass.getSuperClass();
}
}
// 没有父类解析完成
return null;
}
继续跟进:this.componentScanParser.parse(componentScan,sourceClass.getMetadata().getClassName());
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//为我们的扫描器设置beanName的生成器对象
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
/**
* 解析@Scope的ProxyMode属性, 该属性可以将Bean创建问jdk代理或cglib代理
*/
ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
scanner.setScopedProxyMode(scopedProxyMode);
}
else {
Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
}
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
//设置CompentScan对象的includeFilters 包含的属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
//设置CompentScan对象的excludeFilters 包含的属性
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
/**
* 是否懒加载,此懒加载为componentScan延迟加载所有类
*/
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
//包路径com.my.demo
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.add(ClassUtils.getPackageName(declaringClass));
}
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
//真正的进行扫描解析 //todo:(注意这个方法,后续我们要重点跟进)
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
在这个方法里,我们看到它根据注解,获取到了我们需要扫描的包。接着在scanner.doScan(StringUtils.toStringArray(basePackages));去扫描去了。
所以继续跟进scanner.doScan方法:
/**
* Perform a scan within the specified base packages,
* returning the registered bean definitions.
* <p>This method does <i>not</i> register an annotation config processor
* but rather leaves this up to the caller.
* @param basePackages the packages to check for annotated classes
* @return set of beans registered if any for tooling registration purposes (never {@code null})
* 扫描包
*/
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
Assert.notEmpty(basePackages, "At least one base package must be specified");
//创建bean定义的holder对象用于保存扫描后生成的bean定义对象
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
//循环我们的包路径集合
for (String basePackage : basePackages) {
//找到候选的Components //todo:(注意这个方法,后续我们要重点跟进)
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);
//这是默认配置 autowire-candidate
if (candidate instanceof AbstractBeanDefinition) {
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
//获取@Lazy @DependsOn等注解的数据设置到BeanDefinition中
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
//把我们解析出来的组件bean定义注册到我们的IOC容器中(容器中没有才注册)
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;
}
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
继续跟进findCandidateComponents方法
/**
* Scan the class path for candidate components.
* @param basePackage the package to check for annotated classes
* @return a corresponding Set of autodetected bean definitions
*/
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
//todo:(注意这个方法,后续我们要重点跟进)
return scanCandidateComponents(basePackage);
}
}
继续跟进 scanCandidateComponents(basePackage);
private Set<BeanDefinition> scanCandidateComponents(String basePackage) {
Set<BeanDefinition> candidates = new LinkedHashSet<>();
try {
//把传进来的类似 命名空间形式的字符串转换成类似类文件地址的形式,然后在前面加上classpath*:
//即:com.xx=>classpath*:com/xx/**/*.class
String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
resolveBasePackage(basePackage) + '/' + this.resourcePattern;
//扫描指定包路径下面的所有.class文件
Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath);
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
//需要我们的resources集合
for (Resource resource : resources) {
if (traceEnabled) {
logger.trace("Scanning " + resource);
}
//判断当的是不是可读的
if (resource.isReadable()) {
try {
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
//是不是候选的组件
if (isCandidateComponent(metadataReader)) {
//包装成为一个ScannedGenericBeanDefinition
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
//并且设置class资源
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;
}
在此方法中,把要扫描的包"com.my.demo"转换成了路径,
然后去根据路径地址读取包的资源,循环扫描获得符合要求的文件。最终会把符合要求的文件,转换为BeanDefinition,并且返回。 (在这里终于扫描我们自己项目定义的类了)
至此 我们把思绪调回到 doProcessConfigurationClass 方法中
还记得我们跟进了好多步,其实是在doProcessConfigurationClass方法中从parse方法一路跟下来的,就是为了看一下,我们自己定义的类是怎么被扫描,然后被解析成为bean定义的。回忆一下就是doProcessConfigurationClass中的这个方法。
//把我们扫描出来的类变为bean定义的集合 真正的解析
Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan,sourceClass.getMetadata().getClassName());
parse方法看完,接下来我们跟进 doProcessConfigurationClass方法中的:processImports方法
该方法,会把我们有@Import注解的类,完成bean定义
// 处理 @Import annotations
processImports(configClass, sourceClass, getImports(sourceClass), true);
在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 {
//获取我们Import导入进来的所有组件
for (SourceClass candidate : importCandidates) {
//判断该组件是不是实现了ImportSelector的
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
//实例化我们的SelectImport组件
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
//调用相关的aware方法
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
//判断是不是延时的DeferredImportSelectors,是这个类型 不进行处理
if (this.deferredImportSelectors != null && selector instanceof DeferredImportSelector) {
this.deferredImportSelectors.add(
new DeferredImportSelectorHolder(configClass, (DeferredImportSelector) selector));
}
else {//不是延时的
//调用selector的selectImports
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
// 所以递归解析-- 直到成普通组件
Collection<SourceClass> importSourceClasses = asSourceClasses(importClassNames);
processImports(configClass, currentSourceClass, importSourceClasses, false);
}
}
//判断我们导入的组件是不是ImportBeanDefinitionRegistrar,这里不直接调用,只是解析
else if (candidate.isAssignable(ImportBeanDefinitionRegistrar.class)) {
// Candidate class is an ImportBeanDefinitionRegistrar ->
// delegate to it to register additional bean definitions
Class<?> candidateClass = candidate.loadClass();
//实例话我们的ImportBeanDefinitionRegistrar对象
ImportBeanDefinitionRegistrar registrar =
BeanUtils.instantiateClass(candidateClass, ImportBeanDefinitionRegistrar.class);
ParserStrategyUtils.invokeAwareMethods(
registrar, this.environment, this.resourceLoader, this.registry);
//保存我们的ImportBeanDefinitionRegistrar对象 currentSourceClass=所在配置类
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// 当做配置类再解析,注意这里会标记:importedBy, 表示这是Import的配置的类
// 再执行之前的processConfigurationClass()方法 ,
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (BeanDefinitionStoreException ex) {
throw ex;
}
catch (Throwable ex) {
throw new BeanDefinitionStoreException(
"Failed to process import candidates for configuration class [" +
configClass.getMetadata().getClassName() + "]", ex);
}
finally {
this.importStack.pop();
}
}
}
至此我们把焦点再返回到refresh() 方法里。当时我们就是在refresh()方法中
invokeBeanFactoryPostProcessors(beanFactory);一步步跟到 doProcessConfigurationClass的,它去完成class扫描成beanDefinition
接下来 我们看spring是怎么把bean定义转换成 实例bean的
在refresh方法中的 finishBeanFactoryInitialization(beanFactory):
/**
* Finish the initialization of this context's bean factory,
* initializing all remaining singleton beans.
*/
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
// 为我们的bean工厂创建类型转化器 Convert
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
/**
* public class MainConfig implements EmbeddedValueResolverAware{
*
* public void setEmbeddedValueResolver(StringValueResolver resolver) {
this.jdbcUrl = resolver.resolveStringValue("${ds.jdbcUrl}");
this.classDriver = resolver.resolveStringValue("${ds.classDriver}");
}
}
*/
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
// 处理关于aspectj
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
getBean(weaverAwareName);
}
// Stop using the temporary ClassLoader for type matching.
beanFactory.setTempClassLoader(null);
//冻结所有的 bean 定义 , 说明注册的 bean 定义将不被修改或任何进一步的处理
beanFactory.freezeConfiguration();
//实例化剩余的单实例bean //todo:(注意这个方法,后续我们要重点跟进)
beanFactory.preInstantiateSingletons();
}
继续跟进 preInstantiateSingletons方法
public void preInstantiateSingletons() throws BeansException {
if (logger.isDebugEnabled()) {
logger.debug("Pre-instantiating singletons in " + this);
}
//获取我们容器中所有bean定义的名称
List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);
//循环我们所有的bean定义名称
for (String beanName : beanNames) {
//合并我们的bean定义,转换为统一的RootBeanDefinition类型(在), 方便后续处理
RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
/**
* 根据bean定义判断是不是抽象的&& 不是单例的 &&不是懒加载的
*/
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
//是不是工厂bean
if (isFactoryBean(beanName)) {
// 是factoryBean会先生成实际的bean &beanName 是用来获取实际bean的
Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
if (bean instanceof FactoryBean) {
final FactoryBean<?> factory = (FactoryBean<?>) bean;
boolean isEagerInit;
if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
((SmartFactoryBean<?>) factory)::isEagerInit,
getAccessControlContext());
}
else {
isEagerInit = (factory instanceof SmartFactoryBean &&
((SmartFactoryBean<?>) factory).isEagerInit());
}
//调用真正的getBean的流程
if (isEagerInit) {
getBean(beanName);
}
}
}
else {//非工厂Bean 就是普通的bean
getBean(beanName);
}
}
}
//或有的bean的名称 ...........到这里所有的单实例的bean已经记载到单实例bean到缓存中
for (String beanName : beanNames) {
//从单例缓存池中获取所有的对象
Object singletonInstance = getSingleton(beanName);
//判断当前的bean是否实现了SmartInitializingSingleton接口
if (singletonInstance instanceof SmartInitializingSingleton) {
final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
if (System.getSecurityManager() != null) {
AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
smartSingleton.afterSingletonsInstantiated();
return null;
}, getAccessControlContext());
}
else {
//触发实例化之后的方法afterSingletonsInstantiated
smartSingleton.afterSingletonsInstantiated();
}
}
}
}
继续跟进创建bean方法,看它怎么创建的
getBean(beanName);
/**
* 该方法是一个空壳方法,没有任何的实现逻辑 真正的逻辑调用在doGetBean()中
* 该接口是实现了BeanFactory的getBean(String name)接口
* @param name bean的名称 该名称也有可能是bean的alies(别名)
* @return 我们的单例对象
* @throws BeansException
*/
@Override
public Object getBean(String name) throws BeansException {
//真正的获取bean的逻辑
return doGetBean(name, null, null, false);
}
继续跟进doGetBean方法 ,又是一个do开头的方法,是很重要的方法。
/**
* 返回bean的实例,该实例可能是单例bean 也有可能是原型的bean
* @param name bean的名称 也有可能是bean的别名
* @param requiredType 需要获取bean的类型
* @param args 通过该参数传递进来,到调用构造方法时候发现有多个构造方法,我们就可以通过该参数来指定想要的构造方法了
* 不需要去推断构造方法(因为推断构造方法很耗时)
* @param typeCheckOnly 判断当前的bean是不是一个检查类型的bean 这类型用的很少.
* @return 返回一个bean实例
* @throws BeansException 如果bean不能被创建 那么就回抛出异常
*/
@SuppressWarnings("unchecked")
protected <T> T doGetBean(final String name, @Nullable final Class<T> requiredType,
@Nullable final Object[] args, boolean typeCheckOnly) throws BeansException {
/**
* 在这里 传入进来的name 可能是 别名, 也有可能是工厂bean的name,所以在这里需要转换
*/
final String beanName = transformedBeanName(name);
Object bean;
//尝试去缓存中获取对象
Object sharedInstance = getSingleton(beanName);
if (sharedInstance != null && args == null) {
if (logger.isDebugEnabled()) {
if (isSingletonCurrentlyInCreation(beanName)) {
logger.debug("Returning eagerly cached instance of singleton bean '" + beanName +
"' that is not fully initialized yet - a consequence of a circular reference");
}
else {
logger.debug("Returning cached instance of singleton bean '" + beanName + "'");
}
}
/**
* /*
* 如果 sharedInstance 是普通的单例 bean,下面的方法会直接返回。但如果
* sharedInstance 是 FactoryBean 类型的,则需调用 getObject 工厂方法获取真正的
* bean 实例。如果用户想获取 FactoryBean 本身,这里也不会做特别的处理,直接返回
* 即可。毕竟 FactoryBean 的实现类本身也是一种 bean,只不过具有一点特殊的功能而已。
*/
bean = getObjectForBeanInstance(sharedInstance, name, beanName, null);
}
else {
/**
* spring 只能解决单例对象的setter 注入的循环依赖,不能解决构造器注入
*/
if (isPrototypeCurrentlyInCreation(beanName)) {
throw new BeanCurrentlyInCreationException(beanName);
}
/**
* 判断AbstractBeanFacotry工厂是否有父工厂(一般情况下是没有父工厂因为abstractBeanFactory直接是抽象类,不存在父工厂)
* 一般情况下,只有Spring 和SpringMvc整合的时才会有父子容器的概念,
* 比如我们的Controller中注入Service的时候,发现我们依赖的是一个引用对象,那么他就会调用getBean去把service找出来
* 但是当前所在的容器是web子容器,那么就会在这里的 先去父容器找
*/
BeanFactory parentBeanFactory = getParentBeanFactory();
//若存在父工厂,且当前的bean工厂不存在当前的bean定义,那么bean定义是存在于父beanFacotry中
if (parentBeanFactory != null && !containsBeanDefinition(beanName)) {
//获取bean的原始名称
String nameToLookup = originalBeanName(name);
//若为 AbstractBeanFactory 类型,委托父类处理
if (parentBeanFactory instanceof AbstractBeanFactory) {
return ((AbstractBeanFactory) parentBeanFactory).doGetBean(
nameToLookup, requiredType, args, typeCheckOnly);
}
else if (args != null) {
// 委托给构造函数 getBean() 处理
return (T) parentBeanFactory.getBean(nameToLookup, args);
}
else {
// 没有 args,委托给标准的 getBean() 处理
return parentBeanFactory.getBean(nameToLookup, requiredType);
}
}
/**
* 方法参数 typeCheckOnly ,是用来判断调用 #getBean(...) 方法时,表示是否为仅仅进行类型检查获取 Bean 对象
* 如果不是仅仅做类型检查,而是创建 Bean 对象,则需要调用 #markBeanAsCreated(String beanName) 方法,进行记录
*/
if (!typeCheckOnly) {
markBeanAsCreated(beanName);
}
try {
/**
* 从容器中获取 beanName 相应的 GenericBeanDefinition 对象,并将其转换为 RootBeanDefinition 对象
* <bean id="tulingParentCompent" class="com.tuling.testparentsonbean.TulingParentCompent" abstract="true">
<property name="tulingCompent" ref="tulingCompent"></property>
</bean>
<bean id="tulingSonCompent" class="com.tuling.testparentsonbean.TulingSonCompent" parent="tulingParentCompent"></bean>
*/
final RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
//检查当前创建的bean定义是不是抽象的bean定义
checkMergedBeanDefinition(mbd, beanName, args);
/**
*
* @Bean
public DependsA dependsA() {
return new DependsA();
}
@Bean
@DependsOn(value = {"dependsA"})
public DependsB dependsB() {
return new DependsB();
}
* 处理dependsOn的依赖(这个不是我们所谓的循环依赖 而是bean创建前后的依赖)
*/
//依赖bean的名称
String[] dependsOn = mbd.getDependsOn();
if (dependsOn != null) {
// <1> 若给定的依赖 bean 已经注册为依赖给定的 bean
// 即循环依赖的情况,抛出 BeanCreationException 异常
for (String dep : dependsOn) {
//beanName是当前正在创建的bean,dep是正在创建的bean的依赖的bean的名称
if (isDependent(beanName, dep)) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Circular depends-on relationship between '" + beanName + "' and '" + dep + "'");
}
//保存的是依赖 beanName 之间的映射关系:依赖 beanName - > beanName 的集合
registerDependentBean(dep, beanName);
try {
//获取depentceOn的bean
getBean(dep);
}
catch (NoSuchBeanDefinitionException ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"'" + beanName + "' depends on missing bean '" + dep + "'", ex);
}
}
}
//创建单例bean
if (mbd.isSingleton()) {
//把beanName 和一个singletonFactory 并且传入一个回调对象用于回调
sharedInstance = getSingleton(beanName, () -> {
try {
//进入创建bean的逻辑
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
//创建bean的过程中发生异常,需要销毁关于当前bean的所有信息
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}
else if (mbd.isPrototype()) {
// It's a prototype -> create a new instance.
Object prototypeInstance = null;
try {
beforePrototypeCreation(beanName);
prototypeInstance = createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
bean = getObjectForBeanInstance(prototypeInstance, name, beanName, mbd);
}
else {
String scopeName = mbd.getScope();
final Scope scope = this.scopes.get(scopeName);
if (scope == null) {
throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
}
try {
Object scopedInstance = scope.get(beanName, () -> {
beforePrototypeCreation(beanName);
try {
return createBean(beanName, mbd, args);
}
finally {
afterPrototypeCreation(beanName);
}
});
bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
}
catch (IllegalStateException ex) {
throw new BeanCreationException(beanName,
"Scope '" + scopeName + "' is not active for the current thread; consider " +
"defining a scoped proxy for this bean if you intend to refer to it from a singleton",
ex);
}
}
}
catch (BeansException ex) {
cleanupAfterBeanCreationFailure(beanName);
throw ex;
}
}
// Check if required type matches the type of the actual bean instance.
if (requiredType != null && !requiredType.isInstance(bean)) {
try {
T convertedBean = getTypeConverter().convertIfNecessary(bean, requiredType);
if (convertedBean == null) {
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
return convertedBean;
}
catch (TypeMismatchException ex) {
if (logger.isDebugEnabled()) {
logger.debug("Failed to convert bean '" + name + "' to required type '" +
ClassUtils.getQualifiedName(requiredType) + "'", ex);
}
throw new BeanNotOfRequiredTypeException(name, requiredType, bean.getClass());
}
}
return (T) bean;
}
接着跟进createBean 方法
doCreateBean方法:IOC作为容器的体现
/**
* 真的创建bean的逻辑,该方法是最复杂的包含了调用构造函数,给bean的属性赋值
* 调用bean的初始化操作以及 生成代理对象 都是在这里
* @param beanName bean的名称
* @param mbd bean的定义
* @param args 传入的参数
* @return bean的实例
* @throws BeanCreationException if the bean could not be created
* @see #instantiateBean
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
*/
protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args)
throws BeanCreationException {
//BeanWrapper 是对 Bean 的包装,其接口中所定义的功能很简单包括设置获取被包装的对象,获取被包装 bean 的属性描述器
BeanWrapper instanceWrapper = null;
if (mbd.isSingleton()) {
//从没有完成的FactoryBean中移除
instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
}
if (instanceWrapper == null) {
//创建bean实例化 使用合适的实例化策略来创建新的实例:工厂方法、构造函数自动注入、简单初始化 该方法很复杂也很重要
instanceWrapper = createBeanInstance(beanName, mbd, args);
}
//从beanWrapper中获取我们的早期对象
final Object bean = instanceWrapper.getWrappedInstance();
Class<?> beanType = instanceWrapper.getWrappedClass();
if (beanType != NullBean.class) {
mbd.resolvedTargetType = beanType;
}
// Allow post-processors to modify the merged bean definition.
synchronized (mbd.postProcessingLock) {
if (!mbd.postProcessed) {
try {
//进行后置处理 @AutoWired @Value的注解的预解析
applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName);
}
catch (Throwable ex) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Post-processing of merged bean definition failed", ex);
}
mbd.postProcessed = true;
}
}
/**
* 缓存单例到三级缓存中,以防循环依赖
* 判断是否早期引用的Bean,如果是,则允许提前暴露引用
* 判断是否能够暴露早期对象的条件:
* 是否单例
* 是否允许循环依赖
* 是否正在创建的Bean
*/
boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences &&
isSingletonCurrentlyInCreation(beanName));
//上述条件满足,允许中期暴露对象
if (earlySingletonExposure) {
if (logger.isDebugEnabled()) {
logger.debug("Eagerly caching bean '" + beanName +
"' to allow for resolving potential circular references");
}
//把我们的早期对象包装成一个singletonFactory对象 该对象提供了一个getObject方法,该方法内部调用getEarlyBeanReference方法
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
}
// Initialize the bean instance.
Object exposedObject = bean;
try {
//属性赋值 给我们的属性进行赋值(调用set方法进行赋值)
populateBean(beanName, mbd, instanceWrapper);
//进行对象初始化操作(在这里可能生成代理对象)
exposedObject = initializeBean(beanName, exposedObject, mbd);
}
catch (Throwable ex) {
if (ex instanceof BeanCreationException && beanName.equals(((BeanCreationException) ex).getBeanName())) {
throw (BeanCreationException) ex;
}
else {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Initialization of bean failed", ex);
}
}
// 是早期对象暴露
if (earlySingletonExposure) {
/**
* 去缓存中获取到我们的对象 由于传递的allowEarlyReference 是false 要求只能在一级二级缓存中去获取
* 正常普通的bean(不存在循环依赖的bean) 创建的过程中,压根不会把三级缓存提升到二级缓存中
*/
Object earlySingletonReference = getSingleton(beanName, false);
//能够获取到
if (earlySingletonReference != null) {
//经过后置处理的bean和早期的bean引用还相等的话(表示当前的bean没有被代理过)
if (exposedObject == bean) {
exposedObject = earlySingletonReference;
}
//处理依赖的bean
else if (!this.allowRawInjectionDespiteWrapping && hasDependentBean(beanName)) {
String[] dependentBeans = getDependentBeans(beanName);
Set<String> actualDependentBeans = new LinkedHashSet<>(dependentBeans.length);
for (String dependentBean : dependentBeans) {
if (!removeSingletonIfCreatedForTypeCheckOnly(dependentBean)) {
actualDependentBeans.add(dependentBean);
}
}
if (!actualDependentBeans.isEmpty()) {
throw new BeanCurrentlyInCreationException(beanName,
"Bean with name '" + beanName + "' has been injected into other beans [" +
StringUtils.collectionToCommaDelimitedString(actualDependentBeans) +
"] in its raw version as part of a circular reference, but has eventually been " +
"wrapped. This means that said other beans do not use the final version of the " +
"bean. This is often the result of over-eager type matching - consider using " +
"'getBeanNamesOfType' with the 'allowEagerInit' flag turned off, for example.");
}
}
}
}
// Register bean as disposable.
try {
//注册销毁的bean的销毁接口
registerDisposableBeanIfNecessary(beanName, bean, mbd);
}
catch (BeanDefinitionValidationException ex) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Invalid destruction signature", ex);
}
return exposedObject;
}
在doCreateBean方法中,有两个非常重要的方法:
createBeanInstance(beanName, mbd, args); //创建bean的实例
populateBean(beanName, mbd, instanceWrapper); //填充属性
我把这两个方法的源码和注解写到下面。就不再过多解释了。
createBeanInstance方法:给指定的bean创建实例
/**
* Create a new instance for the specified bean, using an appropriate instantiation strategy:
* factory method, constructor autowiring, or simple instantiation.
* @param beanName the name of the bean
* @param mbd the bean definition for the bean
* @param args explicit arguments to use for constructor or factory method invocation
* @return a BeanWrapper for the new instance
* @see #obtainFromSupplier
* @see #instantiateUsingFactoryMethod
* @see #autowireConstructor
* @see #instantiateBean
*/
protected BeanWrapper createBeanInstance(String beanName, RootBeanDefinition mbd, @Nullable Object[] args) {
//从bean定义中解析出当前bean的class对象
Class<?> beanClass = resolveBeanClass(mbd, beanName);
/*
* 检测类的访问权限。默认情况下,对于非 public 的类,是允许访问的。
* if(beanClass 不为null 并且
* 访问修饰符如果不是public 并且
* Bean定义的nonPublicAccessAllowed为false) 题外话:nonPublicAccessAllowed为true的情况下(默认值),即使你不是public的也ok
* 这里会抛出异常
*/
if (beanClass != null && !Modifier.isPublic(beanClass.getModifiers()) && !mbd.isNonPublicAccessAllowed()) {
throw new BeanCreationException(mbd.getResourceDescription(), beanName,
"Bean class isn't public, and non-public access not allowed: " + beanClass.getName());
}
/**
* 该方法是spring5.0 新增加的 如果存在 Supplier 回调,则使用给定的回调方法初始化策略
*/
Supplier<?> instanceSupplier = mbd.getInstanceSupplier();
if (instanceSupplier != null) {
return obtainFromSupplier(instanceSupplier, beanName);
}
/**
* 工厂方法,我们通过配置类来进行配置的话 采用的就是工厂方法,方法名称就是tulingDao就是我们工厂方法的名称
* @Bean会在这创建实例
* Bean
public TulingDao tulingDao() {
return new TulingDao(tulingDataSource());
}
*/
if (mbd.getFactoryMethodName() != null) {
return instantiateUsingFactoryMethod(beanName, mbd, args);
}
/**
* 当多次构建同一个 bean 时,可以使用此处的快捷路径,即无需再次推断应该使用哪种方式构造实例,
* 以提高效率。比如在多次构建同一个 prototype 类型的 bean 时,就可以走此处的捷径。
* 这里的 resolved 和 mbd.constructorArgumentsResolved 将会在 bean 第一次实例
* 化的过程中被设置,在后面的源码中会分析到,先继续往下看。
*/
//判断当前构造函数是否被解析过
boolean resolved = false;
//有没有必须进行依赖注入
boolean autowireNecessary = false;
/**
* 通过getBean传入进来的构造函数是否来指定需要推断构造函数
* 若传递进来的args不为空,那么就可以直接选出对应的构造函数
*/
if (args == null) {
synchronized (mbd.constructorArgumentLock) {
//判断我们的bean定义信息中的resolvedConstructorOrFactoryMethod(用来缓存我们的已经解析的构造函数或者工厂方法)
if (mbd.resolvedConstructorOrFactoryMethod != null) {
//修改已经解析过的构造函数的标志
resolved = true;
//修改标记为true 标识构造函数或者工厂方法已经解析过
autowireNecessary = mbd.constructorArgumentsResolved;
}
}
}
//若被解析过
if (resolved) {
if (autowireNecessary) {
//通过有参的构造函数进行反射调用
return autowireConstructor(beanName, mbd, null, null);
}
else {
//调用无参数的构造函数进行创建对象
return instantiateBean(beanName, mbd);
}
}
/**
* 通过bean的后置处理器进行选举出合适的构造函数对象
*/
Constructor<?>[] ctors = determineConstructorsFromBeanPostProcessors(beanClass, beanName);
/**
* 如果自定义了BeanPostProcessor返回了构造器 或者
* 使用构造器自动装配模式 或者
* 设置了BeanDefinition构造器参数 或者
* 有参数:即getBean(String name, Object... args) 中的args
*
* 则使用自定义的构造器初始化
*/
if (ctors != null || mbd.getResolvedAutowireMode() == AUTOWIRE_CONSTRUCTOR ||
mbd.hasConstructorArgumentValues() || !ObjectUtils.isEmpty(args)) {
//通过构造函数创建对象
return autowireConstructor(beanName, mbd, ctors, args);
}
//使用无参数的构造函数调用创建对象
return instantiateBean(beanName, mbd);
}
populateBean方法:给对象BeanWrapper赋值
/**
*给我们的对象BeanWrapper赋值
* @param beanName bean的名称
* @param mbd bean的定义
* @param bw bean实例包装对象
*/
protected void populateBean(String beanName, RootBeanDefinition mbd, @Nullable BeanWrapper bw) {
//若bw为null的话,则说明对象没有实例化
if (bw == null) {
//进入if 说明对象有属性,bw为空,不能为他设置属性,那就在下面就执行抛出异常
if (mbd.hasPropertyValues()) {
throw new BeanCreationException(
mbd.getResourceDescription(), beanName, "Cannot apply property values to null instance");
}
else {
// Skip property population phase for null instance.
return;
}
}
/**
* 在属性被填充前,给 InstantiationAwareBeanPostProcessor 类型的后置处理器一个修改
* bean 状态的机会。官方的解释是:让用户可以自定义属性注入。比如用户实现一
* 个 InstantiationAwareBeanPostProcessor 类型的后置处理器,并通过
* postProcessAfterInstantiation 方法向 bean 的成员变量注入自定义的信息。
*当时我们发现系统中的的InstantiationAwareBeanPostProcessor.postProcessAfterInstantiationM没有进行任何处理,
*若我们自己实现了这个接口 可以自定义处理.....spring 留给我们自己扩展接口的
*特殊需求,直接使用配置中的信息注入即可。
*/
boolean continueWithPropertyPopulation = true;
//是否持有 InstantiationAwareBeanPostProcessor
if (!mbd.isSynthetic() && hasInstantiationAwareBeanPostProcessors()) {
//获取容器中的所有的BeanPostProcessor
for (BeanPostProcessor bp : getBeanPostProcessors()) {
//判断我们的后置处理器是不是InstantiationAwareBeanPostProcessor
if (bp instanceof InstantiationAwareBeanPostProcessor) {
//进行强制转化
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//若存在后置处理器给我们属性赋值了,那么返回false 可以来修改我们的开关变量,就不会走下面的逻辑了
if (!ibp.postProcessAfterInstantiation(bw.getWrappedInstance(), beanName)) {
// 返回值为是否继续填充 bean
// postProcessAfterInstantiation:如果应该在 bean上面设置属性则返回 true,否则返回 false
// 一般情况下,应该是返回true 。
// 返回 false 的话,将会阻止在此 Bean 实例上调用任何后续的 InstantiationAwareBeanPostProcessor 实
continueWithPropertyPopulation = false;
break;
}
}
}
}
// 如果后续处理器发出停止填充命令,则终止后续操作
if (!continueWithPropertyPopulation) {
return;
}
//获取bean定义的属性
PropertyValues pvs = (mbd.hasPropertyValues() ? mbd.getPropertyValues() : null);
/**
* 判断我们的bean的属性注入模型
* AUTOWIRE_BY_NAME 根据名称注入
* AUTOWIRE_BY_TYPE 根据类型注入
*/
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME || mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
//把PropertyValues封装成为MutablePropertyValues
MutablePropertyValues newPvs = new MutablePropertyValues(pvs);
//根据bean的属性名称注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_NAME) {
autowireByName(beanName, mbd, bw, newPvs);
}
//根据bean的类型进行注入
if (mbd.getResolvedAutowireMode() == AUTOWIRE_BY_TYPE) {
autowireByType(beanName, mbd, bw, newPvs);
}
//把处理过的 属性覆盖原来的
pvs = newPvs;
}
/**
* 这里又是一种后置处理,用于在 Spring 填充属性到 bean 对象前,对属性的值进行相应的处理,
* 比如可以修改某些属性的值。这时注入到 bean 中的值就不是配置文件中的内容了,
* 而是经过后置处理器修改后的内容
*/
boolean hasInstAwareBpps = hasInstantiationAwareBeanPostProcessors();
//判断是否需要检查依赖
boolean needsDepCheck = (mbd.getDependencyCheck() != AbstractBeanDefinition.DEPENDENCY_CHECK_NONE);
if (hasInstAwareBpps || needsDepCheck) {
if (pvs == null) {
pvs = mbd.getPropertyValues();
}
//提出当前正在创建的beanWrapper 依赖的对象
PropertyDescriptor[] filteredPds = filterPropertyDescriptorsForDependencyCheck(bw, mbd.allowCaching);
if (hasInstAwareBpps) {
//获取所有的后置处理器
for (BeanPostProcessor bp : getBeanPostProcessors()) {
if (bp instanceof InstantiationAwareBeanPostProcessor) {
InstantiationAwareBeanPostProcessor ibp = (InstantiationAwareBeanPostProcessor) bp;
//对依赖对象进行后置处理
pvs = ibp.postProcessPropertyValues(pvs, filteredPds, bw.getWrappedInstance(), beanName);
if (pvs == null) {
return;
}
}
}
}
//判断是否检查依赖
if (needsDepCheck) {
checkDependencies(beanName, mbd, filteredPds, pvs);
}
}
/**
* 其实,上面只是完成了所有注入属性的获取,将获取的属性封装在 PropertyValues 的实例对象 pvs 中,
* 并没有应用到已经实例化的 bean 中。而 #applyPropertyValues(String beanName, BeanDefinition mbd, BeanWrapper bw, PropertyValues pvs) 方法,
* 则是完成这一步骤的
*/
if (pvs != null) {
applyPropertyValues(beanName, mbd, bw, pvs);
}
}