运行BeanFactory后置处理器
invokeBeanFactoryPostProcessors
该阶段主要诊断refresh方法中的invokeBeanFactoryPostProcessors方法主要运行BeanFactory后置处理器,之前注册的各种后置处理器都是在这一步运行的,还有SpringBean(贴了Spring注解的bean)的实例化,DI依赖注入以及AOP动态代理都是在这一步完成的 是Spring容器核心方法。
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
// 执行BeanPostFactoryPostProcessor beanFactory还是创建的DefaultListableBeanFactory, get 是从beanFactoryPostProcessors中获取到的这个前边没有设置值核心方法
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
// 在3.3的时候如果有loadTimeWeaver的话需要往容器中添加的很显然没有
// Detect a LoadTimeWeaver and prepare for weaving, if found in the meantime
// (e.g. through an @Bean method registered by ConfigurationClassPostProcessor)
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
PostProcessorRegistrationDelegate#invokeBeanFactoryPostProcessors这个方法主要是核心的执行方法。
我们分步骤分析
4.1创建集合来存储处理的bean信息
先创建了容器用来存放运行的BeanDefinitionRegistryPostProcessors的beanName
// Invoke BeanDefinitionRegistryPostProcessors first, if any.
Set<String> processedBeans = new HashSet<>();
4.2判断是否属于BeanDefinitionRegistry类型来策略的进行处理
判断BeanFactory是否是BeanDefinitionRegistry这种类型,在贴下DefaultListableBeanFactory,根据UML分析很明显是的。
不是的话直接通过入参的beanFactoryPostProcessor执行。
if (beanFactory instanceof BeanDefinitionRegistry){
//着重讲解
}else {
// Invoke factory processors registered with the context instance.
//循环调用process方法
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
下边都是条件成立的情况
4.2.1 第一步强转并创建容器
在属于BeanDefinitionRegistry下先进行强转并创建了两个集合来存储regularProcessor和BeanDefinitionRegistryPostProcessor
//把IOC容器 强制转为BeanDefinitionRegistry类型的
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
//创建一个普通的PostProcessors的list的组件
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
//创建一个BeanDefinitionRegistryPostProcessor类型的list
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
4.2.2循环迭代配置类的处理器
传参中包含beanFactoryPostProcessors(自定义的postProcessor)进行处理
//处理容器硬编码(new 出来的)带入(自定义)的beanFacotryPostProcessors
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
//判断是不是BeanDefinitionRegistryPostProcessor
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
//强制转换
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
//调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry 自定义实现postProcessBeanDefinitionRegistry的方法
registryProcessor.postProcessBeanDefinitionRegistry(registry);
//加入到list集合中
registryProcessors.add(registryProcessor);
}
else {//判断不是BeanDefinitionRegistryPostProcessor
//加入到集合中
regularPostProcessors.add(postProcessor);
}
}
4.2.3创建一个注册的集合
创建一个当前注册的RegistryProcessors的集合
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
4.2.4查询是否存在这种类型的注册器
去容器中查询是否有BeanDefinitionRegistryPostProcessor类型
//第一步:去容器中查询是否有BeanDefinitionRegistryPostProcessor类型的
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
getBeanNamesForType方法
//type就是BeanDefinitionRegistryPostProcessor.class includeNonSingletons(是否包含单例) = true allowEagerInit(是
否允许加载) = false
public String[] getBeanNamesForType(@Nullable Class<?> type, boolean includeNonSingletons, boolean allowEagerInit) { // isConfigurationFrozen() beanDefinition metadata 是否可以被缓存 此时为false为默认值 会走到这个if中
if (!isConfigurationFrozen() || type == null || !allowEagerInit) {
return doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, allowEagerInit);
}
//假如上边条件不成立会直接走缓存获取
Map<Class<?>, String[]> cache =
(includeNonSingletons ? this.allBeanNamesByType : this.singletonBeanNamesByType);
String[] resolvedBeanNames = cache.get(type);
if (resolvedBeanNames != null) {
return resolvedBeanNames;
}
//缓存不存在的话调用跟上边一样的方法只不过最后一个参数为true 是立即被初始化的
resolvedBeanNames = doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true);
if (ClassUtils.isCacheSafe(type, getBeanClassLoader())) {
cache.put(type, resolvedBeanNames);
}
return resolvedBeanNames;
}
对上一步的doGetBeanNamesForType方法说明
主要是先从beanDefinitionNames中获取,beanDefinitionNames属性是在初始化AnnotatedBeanDefinitionReader的时候放入的;在从manualSingletonNames属性中获取 这个属性是在register配置类的时候, 放入的环境属性environment、systemProperties、systemEnvironment。
beanDefinitionNames中获取beanName对应的类型(为了分析方便去除不必要的日志和异常打印)
循环beanDefinitionNames属性获取到对应beanName
for (String beanName : this.beanDefinitionNames) {
//判断存储的beanName是否是别名 aliasMap中获取是否有,这个也是在初始化AnnotatedBeanDefinitionReader的时候放入的
这里只处理非别名的beanName
if (!isAlias(beanName)) {
try {
//先通过beanName获取到本地的BeanDefinition从mergedBeanDefinitions属性中获取,如果不存在的话在从初始化AnnotatedBeanDefinitionReader的时候注册的Map中获取到BeanDefinition,然后包装成RootBeanDefiniton(包装模式)并存储在mergedBeanDefinitions属性中返回rootBeanDefinition 【这里返回的是配置类的包装类】
RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
// 对获取到的BeanDefinition进行判断
if (!mbd.isAbstract() && (allowEagerInit ||
//判断mbd是否是class //是否允许立即加载
(mbd.hasBeanClass() || !mbd.isLazyInit() || isAllowEagerClassLoading()) &&
!requiresEagerInitForType(mbd.getFactoryBeanName()))) {
// 判断是否是factoryBean beanName先根据beanName来预测下是否为FactoryBean的实现类,在判断是否为FactoryBean的实现类 在这里FactoryBean不是
boolean isFactoryBean = isFactoryBean(beanName, mbd);
//获取到包装类是否还有包装类 没有了
BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
//不清楚这一步到底是干啥判断非常复杂
boolean matchFound =
允许立即初始化 不是FactoryBean
(allowEagerInit || !isFactoryBean ||
mbd是立即加载 单例池中包含这个bean
(dbd != null && !mbd.isLazyInit()) || containsSingleton(beanName)) &&
//形参是否包含单例
(includeNonSingletons ||
//是否是单例 beanName对应的BeanFactory是否是单例
(dbd != null ? mbd.isSingleton() : isSingleton(beanName))) &&
//类型是否匹配
isTypeMatch(beanName, type);
//但是根据isFactoryBean为false可以判断这一步不会执行
if (!matchFound && isFactoryBean) {
// 如果是factoryBean的话会把前边加一个&
beanName = FACTORY_BEAN_PREFIX + beanName;
matchFound = (includeNonSingletons || mbd.isSingleton()) && isTypeMatch(beanName, type);
}
//会把beanName添加到结果中
if (matchFound) {
result.add(beanName);
}
}
}catch(Exception e){
//todo 打印异常
}
}
}
循环manualSingletonNames属性获取到对应类型的beanName
for (String beanName : this.manualSingletonNames) {
try {
//判断是否是FactoryBean
if (isFactoryBean(beanName)) {
if ((includeNonSingletons || isSingleton(beanName)) && isTypeMatch(beanName, type)) {
result.add(beanName);
// Match found for this bean: do not match FactoryBean itself anymore.
continue;
}
// 修改下beanname
beanName = FACTORY_BEAN_PREFIX + beanName;
}
// Match raw bean instance (might be raw FactoryBean).
if (isTypeMatch(beanName, type)) {
//添加到结果
result.add(beanName);
}
}
catch (NoSuchBeanDefinitionException ex) {
//打印日志
}
}
是从环境获取到 environment、systemProperties、systemEnvironment这三个属性 很明显不符合,那为啥Spring还这么设计? 是因为manualSingletonNames这个属性中的内容也可能手写的单例模式注册的FactoryBean。
整个第4.2.4步是主要是从已经注册到的BeanFactory中获取到BeanDefinitionRegistryPostProcessor这个类型的类名。获取到的是internalConfigurationAnnotationProcessor。
4.2.5对获取到的beanName处理
【invokeBeanFactoryPostProcessors这个方法中】
for (String ppName : postProcessorNames) {
//判断是不是实现了PriorityOrdered接口的 PriorityOrderedS主要用作排序的
// isTypeMatch这个方法主要是拿着beanName去找到真实的类型,在根据真实的类型去匹配
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//获取到当前的处理器添加的集合中 beanFactory.getBean下边详细介绍
//这里的真实类型就是ConfigurationClassPostProcessor
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//添加到processedBeans的集合中
processedBeans.add(ppName);
}
}
4.2.6对过滤出来的处理器进行排序和备份
//进行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
▲4.2.7处理获取到BeanDefinition
调用获取到的处理器进行处理,处理成功后并从集合中清除。
//调用BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
执行ConfigurationClassPostProcessor方法
在这里只有ConfigurationClassPostProcessor这个处理类调用的是processConfigBeanDefinitions方法
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
//先进行判断如果存在的话就是直接抛出一个异常
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
//这个 也是先进行判断存在抛出异常证明已经被注册过了
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
//往属性registriesPostProcessed中添加这个注册id
this.registriesPostProcessed.add(registryId);
//调用重载方法进行处理
processConfigBeanDefinitions(registry);
}
处理配置类的重载方法真正处理的配置类processConfigBeanDefinitions
//这个registry就是DefaultListableBeanFactory强转的 本质就是最开始创建的BeanFactory 处理配置Bean的BeanDefinition
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
//专门用来存储配置类使用的集合
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
//这一步是在2.2this里边初始化AnnotatedBeanDefinitionReader注册的 包括下边啊6个值
"org.springframework.context.annotation.internalConfigurationAnnotationProcessor"
"org.springframework.context.annotation.internalAutowiredAnnotationProcessor"
"org.springframework.context.annotation.internalCommonAnnotationProcessor"
"org.springframework.context.event.internalEventListenerProcessor"
"org.springframework.context.event.internalEventListenerFactory"
"annotationConfig"
String[] candidateNames = registry.getBeanDefinitionNames();
//迭代Bean定义的名称 找出来配置类放在configCandidates集合中
for (String beanName : candidateNames) {
//去beanDefinitionMap属性中获取 这个属性也是在初始化的时候注册的 获取到BeanDefinition
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//检查该bean定义对象是不是用来描述配置类
if (ConfigurationClassUtils.isFullConfigurationClass(beanDef) ||
ConfigurationClassUtils.isLiteConfigurationClass(beanDef)) {
if (logger.isDebugEnabled()) {
打印日志;
}
}
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
// 没有配置类的话直接返回
if (configCandidates.isEmpty()) {
return;
}
//对配置类的BeanDefinition进行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// Detect any custom bean name generation strategy supplied through the enclosing application context
// bean的名称生成策略
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) { //判断注册类是否是单例的beanRegistry 由继承图可以知道继承了的
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) { //是否需要读取普通beanName 默认为false取反了
//从单例注册器(也就是BeanFactory)中获取internalConfigurationBeanNameGenerator【主要作用是生成beanname】 没有
//这个获取也非常简单,先从单例池中获取没有的话在去早期单例对象中获取有的话刷新下到单例池没有的话在返回一个null
/**很明显这里获取不到因为都没有诸如这个internalConfigurationBeanNameGeneratorBean**/
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
//不存在所以没办法赋值
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
//判断环境是否为null 很显然不是null
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
// 封装了一个配置类的解析器ConfigurationClassParser专门用来解析配置类的。 里边也包括各种已经初始化好的组件比如PropertySourceFactory直接new的、log相关的、还有一些容器
ConfigurationClassParser parser = new ConfigurationClassParser(
//元数据读取工厂, 问题报告 ,环境
this.metadataReaderFactory, this.problemReporter, this.environment,
//资源读取器 ,componentSacnebeanName生成器,注册器
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
//将上边解析的配置类封装的BeanFactoryHolder进行解析
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
//准备保存已经解析的配置类
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
//紧跟着就是一个dowhile循环来解析所有的配置类,循环结束的条件是配置类解析完毕 demo中只有一个
do {
//很重要 通过配置解析器真正的解析配置类
parser.parse(candidates); //下边详细的介绍
//进行校验
parser.validate();
//获取ConfigClass (把解析过的配置bean定义信息获取出来)
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());
}
//@CompentScan是直接注册Bean定义信息的 但是通过获取@Import,@Bean这种的注解还没有注册的bean定义,
this.reader.loadBeanDefinitions(configClasses);
//把系统解析过我们自己的组件放在alreadyParsed
alreadyParsed.addAll(configClasses);
//清除解析过的 配置文件
candidates.clear();
//已经注册的bean定义个数大于最新 开始系统+主配置类的(发生过解析)
if (registry.getBeanDefinitionCount() > candidateNames.length) {
//获取系统+自己解析的+mainconfig的bean定义信息
String[] newCandidateNames = registry.getBeanDefinitionNames();
//系统的+mainconfig的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) {
//老的(系统+mainconfig) 不包含解析的
if (!oldCandidateNames.contains(candidateName)) {
//把当前bean定义获取出来
BeanDefinition bd = registry.getBeanDefinition(candidateName);
//检查是否为解析过的
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
//若不是解析过且通过检查的 把当前的bean定义 加入到candidates中
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方法
public void parse(Set<BeanDefinitionHolder> configCandidates) {
//循环解析
for (BeanDefinitionHolder holder : configCandidates) {
//从holder中获取到BeanDefinition这里是配置类的BeanDefinition
BeanDefinition bd = holder.getBeanDefinition();
try {
//注解形式的bean定义信息 【策略模式】
if (bd instanceof AnnotatedBeanDefinition) {
//解析配置类的bean定义
parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName());
}
//BeanDefinition属于AbstractBeanDefinition这个类型并且 里边有class
else if (bd instanceof AbstractBeanDefinition && ((AbstractBeanDefinition) bd).hasBeanClass()) { parse(((AbstractBeanDefinition) bd).getBeanClass(), holder.getBeanName());
}else {
//其他配置类的解析
parse(bd.getBeanClassName(), holder.getBeanName());
}
}
catch (BeanDefinitionStoreException ex) {}
catch (Throwable ex) {}
}
//处理配置类的import导入的组件模块,经常在SpringBoot中可以看到
this.deferredImportSelectorHandler.process();
}
调用paser的重载方法
protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException {
//封装了到ConfigurationClass中了 metadata、resource、beanname三个属性。
processConfigurationClass(new ConfigurationClass(metadata, beanName));
}
调用processConfigurationClass这个方法
protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
//判断配置类上的@ Conditional注解是是否满足要求,因为贴@ Conditional注解都会实现Condition接口复写matches这个方法,里边返回true才满足要求【这个属于@Condition组件的知识】, 很明显咱们的配置类上没有这个注解
if (this.conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.PARSE_CONFIGURATION)) { return;
}
//先从缓存configurationClasses中获取ConfigurationClass 再启动的时候缓存是没有设置值的
//这个缓存主要是为了解决是否被循环impport
ConfigurationClass existingClass = this.configurationClasses.get(configClass);
if (existingClass != null) {
//判断是否已经被import
if (configClass.isImported()) {
if (existingClass.isImported()) {
//如果已经被import的话就合并在一起 都放到importedBy这个set集合中自动去重
existingClass.mergeImportedBy(configClass);
}
// Otherwise ignore new imported config class; existing non-imported class overrides it.
return;
}
else {
//如果没有被import的话从configurationClasses属性中移除 并且从knownSuperclasses values中移除
this.configurationClasses.remove(configClass);
this.knownSuperclasses.values().removeIf(configClass::equals);
}
}
// 对配置类进行简单的包装 将Class类和注解进行包装source、metadata属性中方便获取
SourceClass sourceClass = asSourceClass(configClass);
do {
//do就是干活的方法, 来处理配置类,通过递归的方式
sourceClass = doProcessConfigurationClass(configClass, sourceClass);
}
while (sourceClass != null);
//将处理好的配置类放入到configurationClasses key是configClass, value也是configClass
this.configurationClasses.put(configClass, configClass);
}
doProcessConfigurationClass
真正开始处理配置类doProcessConfigurationClass
// configClass就是
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
//先判断配置类上有没有贴Componet注解已经Componet的派生注解 {大概思路就是先判断是否不是@Compoent不是的话就看原注解去递归一直找到@Component}
//处理@Componet注解
if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
// 首先递归处理所有的@COmponent类 ①
①processMemberClasses(configClass, sourceClass);
}
//处理@PropertySource注解
// Process any @PropertySource annotations ②
for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), PropertySources.class,
org.springframework.context.annotation.PropertySource.class)) {
if (this.environment instanceof ConfigurableEnvironment) {
②processPropertySource(propertySource);
}
else {
logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
"]. Reason: Environment must implement ConfigurableEnvironment");
}
}
// Process any @ComponentScan annotations
//处理@ComponentScan注解
//@ComponentScans注解所有的属性封装到 AnnotationAttributes中
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
if (!componentScans.isEmpty() &&
//这个还是判断是否有@Conditional是否满足条件
!this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
//循环componentScans的set
for (AnnotationAttributes componentScan : componentScans) {
// The config class is annotated with @ComponentScan -> perform the scan immediately
//很重要==立即执行扫描解析 ③
Set<BeanDefinitionHolder> scannedBeanDefinitions =
this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
// Check the set of scanned definitions for any further config classes and parse recursively if needed
//获取原始的bean定义信息
for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
if (bdCand == null) {
bdCand = holder.getBeanDefinition();
}
//检查当前的bean定义信息是不是配置类 比如MainConfig的bean定义信息
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
//如果扫描出来的类还是一个配置的话调用pase方法递归执行扫描操作
parse(bdCand.getBeanClassName(), holder.getBeanName());
}
}
}
}
// Process any @Import annotations
//处理@Import注解 解析Import 注解的ImportSelector ImportBeanDefinitionRegister,@Bean这种
//存放在ConfigClass中 ④
processImports(configClass, sourceClass, getImports(sourceClass), true);
// Process any @ImportResource annotations
AnnotationAttributes importResource =
AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
//处理 @ImportResource annotations
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);
}
}
// Process individual @Bean methods
// 处理 @Bean methods ⑤
Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
for (MethodMetadata methodMetadata : beanMethods) {
configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
}
// Process default methods on interfaces
//处理接口默认的方法 添加到beanMethods属性中
processInterfaces(configClass, sourceClass);
// Process superclass, if any
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();
}
}
// No superclass -> processing is complete
return null;
}
doProcessConfigurationClass-处理@Componet注解
也就上边的①processMemberClasses(configClass, sourceClass);
//configClass就是配置类的class、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) {
//如果是配置类并且配置内部类的注解和外部配置类注解不一致
if (ConfigurationClassUtils.isConfigurationCandidate(memberClass.getMetadata()) &&
!memberClass.getMetadata().getClassName().equals(configClass.getMetadata().getClassName())) { //添加到集合中
candidates.add(memberClass);
}
}
//排序
OrderComparator.sort(candidates);
for (SourceClass candidate : candidates) {
//如果已经被导入就放入到问题栈中 相当于上下文中存放错误信息的容器
if (this.importStack.contains(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
//如果不包括就推入到导入栈中 防止重复处理
this.importStack.push(configClass);
try {
//递归处理这个内部类配置类
processConfigurationClass(candidate.asConfigClass(configClass));
}
finally {
//从导入栈中推送出去
this.importStack.pop();
}
}
}
}
}
sourceClass.getMemberClasses
public Collection<SourceClass> getMemberClasses() throws IOException {
Object sourceToProcess = this.source;
//先判断类型
if (sourceToProcess instanceof Class) {
//强转
Class<?> sourceClass = (Class<?>) sourceToProcess;
try {
//获取所有内部类
Class<?>[] declaredClasses = sourceClass.getDeclaredClasses();
//返回集合
List<SourceClass> members = new ArrayList<>(declaredClasses.length);
for (Class<?> declaredClass : declaredClasses) {
//包装成一个SourceClass
members.add(asSourceClass(declaredClass));
}
return members;
}
catch (NoClassDefFoundError err) {
// getDeclaredClasses() failed because of non-resolvable dependencies
// -> fall back to ASM below
sourceToProcess = metadataReaderFactory.getMetadataReader(sourceClass.getName());
}
}
// ASM-based resolution - safe for non-resolvable classes as well
MetadataReader sourceReader = (MetadataReader) sourceToProcess;
String[] memberClassNames = sourceReader.getClassMetadata().getMemberClassNames();
List<SourceClass> members = new ArrayList<>(memberClassNames.length);
for (String memberClassName : memberClassNames) {
try {
members.add(asSourceClass(memberClassName));
}
catch (IOException ex) {
//打印日志
}
}
doProcessConfigurationClass-处理@PropertySource注解
也就是②processPropertySource(propertySource)
private void processPropertySource(AnnotationAttributes propertySource) throws IOException {
//先获取到注解的name属性
String name = propertySource.getString("name");
if (!StringUtils.hasLength(name)) {
name = null;
}
//获取到注解的encoding属性
String encoding = propertySource.getString("encoding");
if (!StringUtils.hasLength(encoding)) {
encoding = null;
}
//获取到注解的value属性
String[] locations = propertySource.getStringArray("value");
//获取到注解的ignoreResourceNotFound属性
boolean ignoreResourceNotFound = propertySource.getBoolean("ignoreResourceNotFound");
//获取到注解的factory属性
Class<? extends PropertySourceFactory> factoryClass = propertySource.getClass("factory");
//实例化SourceFactory
PropertySourceFactory factory = (factoryClass == PropertySourceFactory.class ?
DEFAULT_PROPERTY_SOURCE_FACTORY : BeanUtils.instantiateClass(factoryClass));
//对value属性进行迭代
for (String location : locations) {
try {
//从环境中解析这个属性值,解析成一个相对路径
String resolvedLocation = this.environment.resolveRequiredPlaceholders(location);
//通过resourceLoader来获取到这个资源
Resource resource = this.resourceLoader.getResource(resolvedLocation);
//添加到属性source中 先判断propertySourceNames属性中是否包含了这个name,包含了进行替换,最终会添加到propertySourceNames属性中
addPropertySource(factory.createPropertySource(name, new EncodedResource(resource, encoding)));
}
catch (IllegalArgumentException | FileNotFoundException | UnknownHostException | SocketException ex) {
//异常
}
}
}
这个处理最终是把@PropertySource导入的资源加入到了BeanFactory的propertySourceNames(名字)、propertySourceList(名字+资源)
doProcessConfigurationClass-处理@ComponentScan注解
this.componentScanParser.parse③方法
//通过组件扫描器进行真正的解析
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
//封装了一个classpath扫描器
ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry,
componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
//从nameGenerator下边存在的class找到generatorClass
Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
//设置beanName生成器实例对象
scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator :
BeanUtils.instantiateClass(generatorClass));
//从属性中获取到代理模式并设置到扫描器
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));
}
//将resourcePattern直接设置到扫描器中
scanner.setResourcePattern(componentScan.getString("resourcePattern"));
//添加过滤规则,
for (AnnotationAttributes filter : componentScan.getAnnotationArray("includeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addIncludeFilter(typeFilter);
}
}
for (AnnotationAttributes filter : componentScan.getAnnotationArray("excludeFilters")) {
for (TypeFilter typeFilter : typeFiltersFor(filter)) {
scanner.addExcludeFilter(typeFilter);
}
}
//将是否懒加载设置到扫描器中
boolean lazyInit = componentScan.getBoolean("lazyInit");
if (lazyInit) {
scanner.getBeanDefinitionDefaults().setLazyInit(true);
}
//将basePackage设置到扫描器中
Set<String> basePackages = new LinkedHashSet<>();
String[] basePackagesArray = componentScan.getStringArray("basePackages");
for (String pkg : basePackagesArray) {
//去除CONFIG_LOCATION_DELIMITERS中的转移字符串
String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg),
ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS);
Collections.addAll(basePackages, tokenized);
}
// basePackageClasses设置的扫描类的包名
for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
basePackages.add(ClassUtils.getPackageName(clazz));
}
//设置默认的值就是当前类所在的包 添加到扫描包中(SpringBoot就是这么玩儿的)
if (basePackages.isEmpty()) {
basePackages.add(ClassUtils.getPackageName(declaringClass));
}
//扫描器设置不需要扫描的类
scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) {
@Override
protected boolean matchClassName(String className) {
return declaringClass.equals(className);
}
});
/**
* 上边所有都是找到@ComponentScan的属性对扫描器进行设置
*/
//开始执行扫描
return scanner.doScan(StringUtils.toStringArray(basePackages));
}
doProcessConfigurationClass-doScan方法
protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
//创建一个扫描到的BeanDefinition
Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
for (String basePackage : basePackages) {
//扫描出来basePackage下边的所有的beanDefinition
Set<BeanDefinition> candidates = findCandidateComponents(basePackage);① 下边详细讲解
for (BeanDefinition candidate : candidates) {
//解析出BeanDefinition中出scope {是否是单例, 是否使用代理模式} 通过判断@Scope注解的属性没有走默认
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
candidate.setScope(scopeMetadata.getScopeName());
// beanNameGenerator生成一个BeanName{默认看@Compoent中的value值是否有有的话走这个,否则类名首字母小写}
String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
//扫描bean获取到的BeanDefinition都是ScannedGenericBeanDefinition
if (candidate instanceof AbstractBeanDefinition) {
//为扫描到的BeanDefinition设置一些值{比如:懒加载、autowiredMode、DependencyCheck、InitMethodName、EnforceInitMethod、DestroyMethodName、EnforceDestroyMethod} ; 如果有@Condition中并且匹配成功的话往autowireCandidate属性中设置值。
postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
}
//对@Lazy、@ Primary、@ DependsOn、@ Role、@ Description这些注解的属性值设置到BeanDefinition中
if (candidate instanceof AnnotatedBeanDefinition) {
AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate);
}
if (checkCandidate(beanName, candidate)) { //校验BeanFactory中是否包含这种BeanDefinition true没有包含
//包装以一个BeanDefinitionHolder
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
//根据@Scope标签中配置的是否使用代理默认没有 如果使用代理对应的对BeanDefinitionHoler 如果使用的话这里是使用包装模式对原来的BeanDefinitionHolder进行了一次包装并且指定了使用了那种的代理模式。
definitionHolder =
AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//添加到上边传的容器中
beanDefinitions.add(definitionHolder);
//将当前的BeanDefinitionHodler注册到BeanFactory中 就是放到DefaultListableBeanFactory的beanDefinitionMap中
registerBeanDefinition(definitionHolder, this.registry);
}
}
}
return beanDefinitions;
}
doProcessConfigurationClass-扫描到的BeanDefinition类型继承图UML
findCandidateComponents(basePackage)
查找指定包路径下边的所有的贴了注解的bean
public Set<BeanDefinition> findCandidateComponents(String basePackage) {
//先判断是不是扫描index 这里不是
if (this.componentsIndex != null && indexSupportsIncludeFilters()) {
return addCandidateComponentsFromIndex(this.componentsIndex, basePackage);
}
else {
//调用扫描package方法
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[] resources = getResourcePatternResolver().getResources(packageSearchPath);
//日志打印参数
boolean traceEnabled = logger.isTraceEnabled();
boolean debugEnabled = logger.isDebugEnabled();
for (Resource resource : resources) {
//如果存在
if (resource.isReadable()) {
try {
//获取到元数据读取器 就是将贴的注解都封装起来
MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource);
//判断是否存在@Component注解如果存在的话就添加到返回的队列中
if (isCandidateComponent(metadataReader)) {
ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader);
sbd.setSource(resource);
if (isCandidateComponent(sbd)) {
candidates.add(sbd);
}
}
}
}
}
}
catch (IOException ex) {}
return candidates;
}
到此4.2.3@ComponetScan注解已经完了主要的作用就是把package下边的所有贴了Spring标签的注解类都封装成BeanDefinitionHolder放入到Ioc容器中。
doProcessConfigurationClass-处理@Conditional注入的配置类
private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass,
Collection<SourceClass> importCandidates, boolean checkForCircularImports) {
//先判断
if (importCandidates.isEmpty()) {
return;
}
//如果是循环import并且已经被导入stack中经会记录循环错误信息
if (checkForCircularImports && isChainedImportOnStack(configClass)) {
this.problemReporter.error(new CircularImportProblem(configClass, this.importStack));
}
else {
//先推入到导入栈
this.importStack.push(configClass);
try {
//对导入的配置类进行迭代
for (SourceClass candidate : importCandidates) {
//如果使用的是@ImportSelector这个注解的话进行if中的操作
if (candidate.isAssignable(ImportSelector.class)) {
// Candidate class is an ImportSelector -> delegate to it to determine imports
Class<?> candidateClass = candidate.loadClass();
//先实例化导入的装配类
ImportSelector selector = BeanUtils.instantiateClass(candidateClass, ImportSelector.class);
//运行通知接口 被导入了 实现了AwareMethods的类
ParserStrategyUtils.invokeAwareMethods(
selector, this.environment, this.resourceLoader, this.registry);
//判断selector是否是 DeferredImportSelector子类
if (selector instanceof DeferredImportSelector) {
//如果是的话直接进行处理
this.deferredImportSelectorHandler.handle(configClass, (DeferredImportSelector) selector);
}
else {
//不是的话先获取到导入的className
String[] importClassNames = selector.selectImports(currentSourceClass.getMetadata());
//获取到导入的classname的注解信息
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);
//添加到BeanFactory的importBeanDefinitionRegistrars这个属性中
configClass.addImportBeanDefinitionRegistrar(registrar, currentSourceClass.getMetadata());
}
else {
// process it as an @Configuration class 处理导入
this.importStack.registerImport(
currentSourceClass.getMetadata(), candidate.getMetadata().getClassName());
//处理 就去configurationClasses属性查看是否已经被导入如果被导入统一放到importedBy这个Set集合中在刷新下属性
processConfigurationClass(candidate.asConfigClass(configClass));
}
}
}
catch (Throwable ex) {}
finally {
this.importStack.pop();
}
}
}
doProcessConfigurationClass-处理@Bean注解
先获取到配置类下边所有beanMethd
private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) {
//获取到元数据信息
AnnotationMetadata original = sourceClass.getMetadata();
//判断是否包含@Bean这个注解
Set<MethodMetadata> beanMethods = original.getAnnotatedMethods(Bean.class.getName());
//如果数量>1由于jvm每次加载同一个类的顺序是不同的,因此需要通过两中不同的方式去加载 为了保证加载的顺序
就使用asm的方式加载方法, original这种是原始的加载方法
if (beanMethods.size() > 1 && original instanceof StandardAnnotationMetadata) {
try {
//读取到元数据信息
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) {
for (MethodMetadata beanMethod : beanMethods) { if (beanMethod.getMethodName().equals(asmMethod.getMethodName())) {
selectedMethods.add(beanMethod);
break;
}
}
}
if (selectedMethods.size() == beanMethods.size()) {
beanMethods = selectedMethods;
}
}
}
catch (IOException ex) {}
}
return beanMethods;
}
然后放置到BeanFactory的beanMethods属性中。
4.2.8获取到RegistryPostProcessor
从BeanFactory中获取到自定义和其他的后置处理器,因为在4.2.7已经将所有的SpringBean注册到Spring容器中了
// Next, invoke the BeanDefinitionRegistryPostProcessors that implement Ordered.
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
可以参考4.2.4这一步已经有详细说明了。
能够获取到org.springframework.context.annotation.internalConfigurationAnnotationProcessor处理器,也是在初始化的时候注入的。
排除被处理过,并且没有实现Ordered的处理器
//第二步:去容器中查询是否有BeanDefinitionRegistryPostProcessor类型的
for (String ppName : postProcessorNames) {
//只处理那些没有被处理的并且实现了ordered的注册器
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
//加到以处理的list中
processedBeans.add(ppName);
}
}
对获取到的处理器进行排序并且添加到BeanFactory中
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
进行处理
//调用BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
4.2.9最终兜底在获取一次RegistryPostProcessor
在添加一次防止没有被处理的RegistryPostProcessor
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
// 兜底方案在执行一下以防有没有被执行的
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
if里边的在这里已经被执行完毕了!
4.3从容器中获取BeanFactoryPostProcessor并进行处理
4.3.1先获取后置处理器
//去IOC 容器中获取BeanFactoryPostProcessor 类型的
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
4.3.2对后置处理器进行分类
//分离实现了PriorityOrdered接口的 Ordered 接口的 普通的
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//判断4.2步骤处理的处理器中是否包含 如果包含的话不做任何处理
if (processedBeans.contains(ppName)) {
// skip - already processed in first phase above
}
//后置处理器是否是PriorityOrdered的子类
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
//后置处理器中是否是Ordered的子类
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
//存放在这种容器中
nonOrderedPostProcessorNames.add(ppName);
}
}
4.3.3对分类出来的 priorityOrdered进行处理
//调用 PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
在咱们初始化的时候是没有的
4.3.4对分类出来的orderedPostProcessor进行处理
// Next, invoke the BeanFactoryPostProcessors that implement Ordered.
///调用 Ordered.
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>();
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
也是没有的
4.3.5 对普通的处理器进行处理 最终并清空缓存
// Finally, invoke all other BeanFactoryPostProcessors.
//调用普通的
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>();
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
// Clear cached merged bean definitions since the post-processors might have
// modified the original metadata, e.g. replacing placeholders in values...
beanFactory.clearMetadataCache();
如果自定义实现的话会只进行执行processor接口的逻辑的。
拉勾教育作为拉勾旗下专为互联网人打造的职场专业能力提升平台,邀请到了国内外知名互联网公司的资深员工,提纲挈领的为各位同学分享宝贵实战经验。并按照专业技术能力全盘图谱、面试难点、实战案例分析等对标阿里 P7 能力模型,为学员提供更全、更深、更实用的技能进阶方法。同时每个班级,更有由班主任、导师组成的“双师辅导”队伍,为学员提供 7 * 12+ 小时的在线服务,让你从此摆脱懒惰,摆脱无人解惑。紧握拉勾教育,实现更多人生可能。
5. 注册BeanPostProcessor
主要讲解refresh的registerBeanPostProcessors这一步,调用的是重载方法registerBeanPostProcessors
5.1获取到Bean后置处理器
String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanPostProcessor.class, true, false);
//获取到Bean后置处理器+1+长度 在注册的时候防止由于循环依赖导致的扩容影响性能
int beanProcessorTargetCount = beanFactory.getBeanPostProcessorCount() + 1 + postProcessorNames.length;
5.2往BeanFactory注入一个后置处理器校验
beanFactory.addBeanPostProcessor(new BeanPostProcessorChecker(beanFactory, beanProcessorTargetCount));
BeanPostProcessorChecker主要用来校验bean 查看下校验方法
@Override
public Object postProcessAfterInitialization(Object bean, String beanName) {
if (!(bean instanceof BeanPostProcessor) && !isInfrastructureBean(beanName) &&
this.beanFactory.getBeanPostProcessorCount() < this.beanPostProcessorTargetCount) {
if (logger.isInfoEnabled()) {
logger.info("Bean '" + beanName + "' of type [" + bean.getClass().getName() +
"] is not eligible for getting processed by all BeanPostProcessors " +
"(for example: not eligible for auto-proxying)");
}
}
return bean;
}
主要用来打印日志的
5.3根据实现的不同进行分类并装到不同的容器中
List<BeanPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<BeanPostProcessor> internalPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
//判断师傅属于PriorityOrdered类型的
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
BeanPostProcessor pp = beanFactory.getBean(ppName, BeanPostProcessor.class);
priorityOrderedPostProcessors.add(pp);
if (pp instanceof MergedBeanDefinitionPostProcessor) {
//是否属于MergedBeanDefinitionPostProcessor这种类型
internalPostProcessors.add(pp);
}
}
//判断是否属于Ordered类型的是的话放到orderedPostProcessorNames这个了里边
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
//其他的放到这个集合中
nonOrderedPostProcessorNames.add(ppName);
}
}
5.4对于有限的处理器先进行处理
// First, register the BeanPostProcessors that implement PriorityOrdered.
sortPostProcessors(priorityOrderedPostProcessors, beanFactory); //先进行排序
registerBeanPostProcessors(beanFactory, priorityOrderedPostProcessors); //执行
这里能够获取到两个处理器:普通的注解CommonAnnotationBeanPostProcessor(@Component)、AutowiredAnnotationBeanPostProcessor(@Autowired)分别对应的就是bean注入和依赖注入。
registerBeanPostProcessors方法主要是将这两个处理器放到BeanFactory中。
public void addBeanPostProcessor(BeanPostProcessor beanPostProcessor) {
// Remove from old position, if any 先从老的处理器中移除
this.beanPostProcessors.remove(beanPostProcessor);
// Track whether it is instantiation/destruction aware 判断是否实现需要初始化通知做个标记
if (beanPostProcessor instanceof InstantiationAwareBeanPostProcessor) {
this.hasInstantiationAwareBeanPostProcessors = true;
}
if (beanPostProcessor instanceof DestructionAwareBeanPostProcessor) { //判断是否需要销毁时通知做个标记
this.hasDestructionAwareBeanPostProcessors = true;
}
// Add to end of list
this.beanPostProcessors.add(beanPostProcessor); //在放入到beanPostProcessors这个属性中
}
贴上两个处理器的继承图
CommonAnnotationBeanPostProcessor
AutowiredAnnotationBeanPostProcessor