invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory)
循环遍历传递进来的beanFactoryPostProcesser, 这个集合一般情况下为空, 除非我们自己调用容器的addBeanFactoryPostProcessor方法;
因为一般是空,所以跳过
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
xxxx;
// 这个beanFactoryPostProcessors集合一般情况下都是空的,除非我们手动调用容器的addBeanFactoryPostProcessor方法
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
// BeanDefinitionRegistryPostProcessor是一个特殊的BeanFactoryPostProcessor,需要先执行postProcessBeanDefinitionRegistry方法
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
xxx;
}
然后,拿到ConfigurationClassPostProcessor,。他实现了BeanDefinitionRegistryPostProcessor,判断是否实现了PriorityOrdered接口,如果实现了要最优先调用,排序 -> 添加 -> 调用
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
xxxx;
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 判断这个类是否还实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 这里调用了getBean,所以生成一个BeanDefinitionRegistryPostProcessor的bean对象
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
// 排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
// 添加
registryProcessors.addAll(currentRegistryProcessors);
// 执行postProcessBeanDefinitionRegistry方法
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
xxx;
}
然后,添加实现了Order接口的BeanDefinitionRegistryPostProcessors,同样的,排序 - > 添加 ->调用:
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
xxxx;
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
// 判断这个类是否还实现了PriorityOrdered接口
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
// 这里调用了getBean,所以生成一个BeanDefinitionRegistryPostProcessor的bean对象
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
xxx;
}
最后,普通BeanDefinitionRegistryPostProcessors,
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
xxxx;
// Finally, invoke all other BeanDefinitionRegistryPostProcessors until no further ones appear.
// 最后,最后其他普通的BeanDefinitionRegistryPostProcessors的postProcessBeanDefinitionRegistry方法
boolean reiterate = true;
// 在一个BeanDefinitionRegistryPostProcessor中可以注册另一个BeanDefinitionRegistryPostProcessor,所以需要递归找出所有的BeanDefinitionRegistryPostProcessor
// 一个没有实现PriorityOrdered接口的BeanDefinitionRegistryPostProcessor如果在内部注册了一个实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor,那么就是没有实现PriorityOrdered接口的先执行
while (reiterate) {
reiterate = false;
// 这里会再一次拿到实现了PriorityOrdered接口或Ordered接口的BeanDefinitionRegistryPostProcessor,所以需要processedBeans进行过滤
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();
}
xxx;
}
然后要去调用invokeBeanFactoryPostProcessors, 注意BeanDefinitionRegistryPostProcessor继承了BeanFactoryPostProcessor:
*/
public interface BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor {
/**
* Modify the application context's internal bean definition registry after its
* standard initialization. All regular bean definitions will have been loaded,
* but no beans will have been instantiated yet. This allows for adding further
* bean definitions before the next post-processing phase kicks in.
* @param registry the bean definition registry used by the application context
* @throws org.springframework.beans.BeansException in case of errors
*/
void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException;
}
因此对于我们的ConfigurationClassPostProcessor,因为他实现了BeanDefinitionRegistryPostProcessor和PriorityOrdered,因此在第一步和invokeBeanFactoryPostProcessors都会被调用。
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
首先,为每个配置类(加了@Configuration)注册了cglib动态代理:
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
xxx;
// 判断是否需要对AppConfig类生成代理对象
enhanceConfigurationClasses(beanFactory);
// Bean的后置处理器
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) {
xxx;
// 生成AppConfig的代理对象
ConfigurationClassEnhancer enhancer = new ConfigurationClassEnhancer();
}
动态代理类是为了在获取对象时,先从Bean IOC容器中获取,而不是使用自己new出来的对象。
拿到@ComponentScan
protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
throws IOException {
xxx;
Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
xxx;
}
拿到以后解析,将包名换成物理路径名,进行扫描,得到指定目录下所有的类。
读到所有的类以后,