ConfigurationClassPostProcessor
是一个用于处理配置类的处理器,它在Spring启动过程中在invokeBeanFactoryPostProcessors
方法中被调用:
- 获取beanFactory中的BeanDefinitionRegistryPostProcessor
- 筛选实现了PriorityOrdered接口的BeanDefinitionRegistryPostProcessor
- 调用BeanDefinitionRegistryPostProcessor的postProcessBeanDefinitionRegistry方法
下文我们分析一下ConfigurationClassPostProcessor
的postProcessBeanDefinitionRegistry
方法做了什么:
1 | public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { |
检查beanDefinition是否是候选的配置类
检查beanDefinition是否是候选的配置类由ConfigurationClassUtils.checkConfigurationClassCandidate
完成。
1 | public static boolean checkConfigurationClassCandidate(BeanDefinition beanDef, MetadataReaderFactory metadataReaderFactory) { |
解析配置文件
从beanFactory中筛选出所有的配置文件的定义,放在Set<BeanDefinitionHolder> candidates
中。
然后新建一个ConfigurationClassParser
:
1 | ConfigurationClassParser parser = new ConfigurationClassParser( |
用ConfigurationClassParser
来解析配置文件。
parse
1 | public void parse(Set<BeanDefinitionHolder> configCandidates) { |
processConfigurationClass
1 | protected void processConfigurationClass(ConfigurationClass configClass) throws IOException { |
doProcessConfigurationClass
doProcessConfigurationClass用于处理并建立一个完整的ConfigurationClass
1 | protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { |
处理配置类中的成员类
processMemberClasses
递归处理处理配置类中的成员类(内嵌类)
1 | private void processMemberClasses(ConfigurationClass configClass, SourceClass sourceClass) throws IOException { |
处理@PropertySource注释
AnnotationConfigUtils.attributesForRepeatable
获取注释的属性
1 | static Set<AnnotationAttributes> attributesForRepeatable(AnnotationMetadata metadata, |
- StandardAnnotationMetadata.getAnnotationAttibutes
1 | public Map<String, Object> getAnnotationAttributes(String annotationName, boolean classValuesAsString) { |
AnnotatedElementUtils.getMergedAnnotationAttributes
获取注释属性
1 | public static AnnotationAttributes getMergedAnnotationAttributes(AnnotatedElement element, |
processPropertySource
处理PropertySource注释,将resource包装成PropertySource,添加到AbstractEnvironment的MutablePropertySources propertySources中
1 | private void processPropertySource(AnnotationAttributes propertySource) throws IOException { |
addPropertySource
添加PropertySource
1 | private void addPropertySource(PropertySource<?> propertySource) { |
处理@ComponentScan注释
ComponentScanAnnotationParser.parse
扫描@ComponentScan注释中指定的位置
1 | public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { |
ClassPathBeanDefinitionScanner.doScan
扫描从@ComponentScan中获取要扫描的路径,生成BeanDefinition
1 | protected Set<BeanDefinitionHolder> doScan(String... basePackages) { |
ClassPathScanningCandidateComponentProvider.findCandidateComponents
扫描路径,生成每个类的beanDefinition,以便之后的步骤实例化类
1 | public Set<BeanDefinition> findCandidateComponents(String basePackage) { |
ClassPathScanningCandidateComponentProvider.isCandidateComponent
判断是否是一个Component
1 | protected boolean isCandidateComponent(MetadataReader metadataReader) throws IOException { |
PathMatchingResourcePatternResolver.getResource
扫描路径,将目录下的类文件包装成Resource
1 | public Resource[] getResources(String locationPattern) throws IOException { |
- PathMatchingResourcePatternResolver.findPathMatchingResource
1 | protected Resource[] findPathMatchingResources(String locationPattern) throws IOException { |
- PathMatchingResourcePatternResolver.findAllClassPathResources
1 | protected Resource[] findAllClassPathResources(String location) throws IOException { |
- PathMatchingResourceResolver.doFindAllClassPathResource
1 | protected Set<Resource> doFindAllClassPathResources(String path) throws IOException { |
- PathMatchingResourcePatternResolver.doFindPathMatchingFileResource
1 | protected Set<Resource> doFindPathMatchingFileResources(Resource rootDirResource, String subPattern) throws IOException { |
- PathMatchingResourcePatternResolver.doFindMatchingFileSystemResources
1 | protected Set<Resource> doFindMatchingFileSystemResources(File rootDir, String subPattern) throws IOException { |
- PathMatchingResourcePatternResolver.retrieveMatchingFiles
1 | protected Set<File> retrieveMatchingFiles(File rootDir, String pattern) throws IOException { |
- PathMatchingResourcePatternResolver.doRetrieveMatchingFiles
1 | protected void doRetrieveMatchingFiles(String fullPattern, File dir, Set<File> result) throws IOException { |
处理@Import注释
- ConfigurationClassParser.getImports
1 | private Set<SourceClass> getImports(SourceClass sourceClass) throws IOException { |
- ConfigurationClassParser.processImports
1 | private void processImports(ConfigurationClass configClass, SourceClass currentSourceClass, |
处理@ImportResource注释
1 | if (sourceClass.getMetadata().isAnnotated(ImportResource.class.getName())) { |
处理被@Bean注释的方法
1 | // 获取所有被@Bean注释的方法 |
ConfigurationClassParser.retrieveBeanMethodMetadata
获取所有被@Bean注释的方法
1 | private Set<MethodMetadata> retrieveBeanMethodMetadata(SourceClass sourceClass) { |
加载配置文件的bean definition
- ConfigurationClassBeanDefinitionReader.loadBeanDefinition
1 | public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) { |
- ConfigurationClassBeanDefinitionReader.loadBeanDefinitionsForConfigurationClass
1 | private void loadBeanDefinitionsForConfigurationClass(ConfigurationClass configClass, TrackedConditionEvaluator trackedConditionEvaluator) { |
postProcessBeanFactory
1 | public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) { |
- ConfigurationClassPostProcessor.enhanceConfigurationClasses
1 | public void enhanceConfigurationClasses(ConfigurableListableBeanFactory beanFactory) { |
- ConfigurationClassEnhancer.enhance
1 | public Class<?> enhance(Class<?> configClass, ClassLoader classLoader) { |