BeanFactoryPostProcess及子类BeanDefinitionRegistryPostProcess
1.BeanFactoryPostProcess是bean工厂后置处理器。目的是为了干预bean工厂(DefaultListableBeanFactory)的处理过程。
在Spring扫描之后调用。一般由程序员提供
@FunctionalInterface public interface BeanFactoryPostProcessor { /** * Modify the application context's internal bean factory after its standard * initialization. All bean definitions will have been loaded, but no beans * will have been instantiated yet. This allows for overriding or adding * properties even to eager-initializing beans. * @param beanFactory the bean factory used by the application context * @throws org.springframework.beans.BeansException in case of errors */ void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException; }
2.BeanDefinitionRegistryPostProcessor继承BeanFactoryPostProcess
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; }
一般由Spring容器提供(ConfigurationClassPostProcessor)。在Spring扫描bean之前调用,完成Spring扫描bean的功能。
调用优先于BeanFactoryPostProcess。是顶级的bean工厂后置处理器。
Bean的扫描过程
bean的扫描在beanFactoryPostProcess的子类实现类ConfigurationClassPostProcessor执行后置处理器postProcessBeanDefinitionRegistry()方法执行的。ConfigurationClassPostProcessor这个类是Spring容器开天辟地创建的。
在postProcessBeanDefinitionRegistry()方法中完成bean的parse->validate。
- parse解析的过程中会调用ClassPathBeanDefinitionScanner.scan()方法。
- isCandidateComponent()方法,根据提供的TypeFilter,是不是匹配相应的注解修饰。默认是@Component。
- 判断类是不是独立的,或者是带有@Lookup注解的抽象类。
return ( metadata.isIndependent() && (metadata.isConcrete() || ( metadata.isAbstract() && metadata.hasAnnotatedMethods(Lookup.class.getName())) ) );
Mybatis 的@MapperScan扫描机制
1.Mybatis定义一个类ClassPathMapperScanner。它继承了Spring提供的ClassPathBeanDefinitionScanner类。提供了一个方法registerFilters(),内部调用了addIncludeFilter((metadataReader, metadataReaderFactory) -> true)方法。使其永远返回true。
2.重写了isCandidateComponent()方法。判断类是不是接口。