ConfigurationClassPostProcessor的加载,在带Xml配置文件的ClassPathApplicationContext中加载和用SpringBoot的SpringApplication来加载,是不同的。分述如下:
- 在带Xml配置文件的ClassPathApplicationContext中加载时,
- 调用AbstractApplicationContext中调用refresh()方法,在refresh()方法中再调用obtainFreshBeanFactory方法,在obtainFreshBeanFactory()方法中又调用loadBeanDefinitions方法,然后会有一系列的loadBeanDefinitions方法,直到调用XmlBeanDefinitionReader中的loadBeanDefintions方法,此时会进而调用doLoadBeanDefinitions方法,然后会调用到DefaultBeanDefintionDocumentReader的registerBeanDefintions方法,再doRegisterBeanDefinitions方法,此时要干正事了。
- 在doRegisterBeanDefinitions方法中,会先后调用三个方法:preProcessXml、parseBeanDefinitions、postProcessXml。在parseBeanDefinitions方法中,以会调用一系列的parse方法,直到调用ComponentScanBeanDefinitionParser的parse方法,这里会new一个ClassPathBeanDefinitonScanner来,调用这个scanner的doScan方法。
- 在doScan方法中,会先调用findCandidateComponents方法,再调用registerComponents方法。在registerComponents方法中调用AnnotationConfigUtils的静态方法registerAnnotionConfigProcessors。在这个方法里会注册内部的、所有用于注解的BFPP和BPP,其中就有ConfigurationClassPostProcessor。
- 用SpringBoot的SpringApplication来加载时,
- 有SpringApplication的run方法启动,会做一系列的事,会先启动任务监测器StopWatch,再从spring.factories在内存中的缓存map里读取SpringApplicationRunListener再启动11个注册的Listener,再准备环境Environment,再根据WebApplicationType类型SERVLET创建ApplicationContext的实例AnnotationConfigServletWebServerApplicationContext,在这个ApplicationContext的构造方法中会给两个属性赋值:reader和scannner,其中的reader为AnnotatedBeanDefinitionReader,在reader的构造方法中调用了AnnotionConfigUtils的registerAnnotationConfigProcessors方法,后面的过程同上。