前文传送门:
本文内容:
AbstractApplicationContext#refresh
前部分的一点小内容BeanFactoryPostProcessor
调用过程详解mybatis
是如何使用本节知识整合spring的?
正文:
在Spring中,一共分为BeanFactoryPostProcessor
和BeanPostProcessor
两类后置处理器,他们主要的职责如下:
BeanFactoryPostProcessor
:负责beanClass
到beanDefinition
的过程,包括但不限于寻找合适的beanClass
,创建beanDefinition
,修改beanDefinition
,将beanDefinition
注册到BeanFactory
中BeanPostProcessor
:负责beanDefinition
到bean
的过程,包括但不限于bean
的属性赋值,初始化
本次主要分析BeanFactoryPostProcessor
的调用过程,下面是BeanFactoryPostProcessor
调用过程的大体流程图,也是本文想要表述的大概内容,原图链接: BeanFactoryPostProcessor调用过程
refresh的前半段流程
// 启动前的准备工作 prepareRefresh(); // 由于web项目中并不会先引入DefaultListableBeanFactory,在这里通知子类刷新BeanFactory // 而我们是使用new AnnotationConfigApplicationContext()的方式,就是直接返回之前引入的DefaultListableBeanFactory ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory(); // 准备工作,给DefaultListableBeanFactory填充属性 prepareBeanFactory(beanFactory); // 留于子类调用的扩展方法 postProcessBeanFactory(beanFactory); // 调用实现BeanFactoryPostProcessor的后置处理器, // 其实就是我们在new AnnotatedBeanDefinitionReader时注册的解析配置类的后置处理器ConfigurationClassPostProcessor // 这里会解析配置类以及处理解析配置类后所引入的所有BeanFactoryPostProcessor invokeBeanFactoryPostProcessors(beanFactory); // 注册上一步解析出来的所有的BeanPostProcessor // 注册逻辑和上一步大致相同,PriorityOrdered-> Ordered -> 普通的 registerBeanPostProcessors(beanFactory);
prepareRefresh
// 设置容器状态 this.closed.set(false); this.active.set(true);
prepareBeanFactory
// 添加一个ApplicationContextAwareProcessor,用于bean初始化前调用一系列的Aware接口回调 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this)); // 用于处理实现ApplicationListener接口的bean,bean初始化后添加监听 beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
invokeBeanFactoryPostProcessors(重点)
此方法将解析配置类以及处理解析配置类后所引入的所有BeanFactoryPostProcessor
温馨提醒:内容较多,还请耐心阅读~
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) { //由于之前注册的都是BeanDefinition,此时还并没有生产任何的BeanFactoryPostProcessor,所以getBeanFactoryPostProcessors是空的 PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors()); }
invokeBeanFactoryPostProcessors
前部分主要是寻找ConfigurationClassPostProcessor并将它实例化
//放置已处理的beanName Set<String> processedBeans = new HashSet<>(); //放置常规的后置处理器,就是只实现了BeanFactoryPostProcessor接口的 List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>(); //放置实现了BeanDefinitionRegistryPostProcessor接口的,之前我们注册的后置处理器中只有ConfigurationClassPostProcessor实现了 List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>(); //放置当前的RegistryProcessors List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>(); //查找实现了BeanDefinitionRegistryPostProcessor接口的BeanName,其实就只有一个ConfigurationClassPostProcessor String[] postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false); for (String ppName : postProcessorNames) { //ConfigurationClassPostProcessor同样实现了PriorityOrdered接口 if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) { //注意这里调用了getBean方法,生产了ConfigurationClassPostProcessor,放到currentRegistryProcessors集合中 currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class)); processedBeans.add(ppName); } } //排序 sortPostProcessors(currentRegistryProcessors, beanFactory); //将生产出来的后置处理器放到集合中 registryProcessors.addAll(currentRegistryProcessors);
接下来就开始调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法
//调用ConfigurationClassPostProcessor的postProcessBeanDefinitionRegistry方法 invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry); private static void invokeBeanDefinitionRegistryPostProcessors( Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) { //循环BeanDefinitionRegistryPostProcessor进行调用 for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) { postProcessor.postProcessBeanDefinitionRegistry(registry); } }
postProcessBeanDefinitionRegistry
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) { processConfigBeanDefinitions(registry); }
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) { //放置候选配置类 List<BeanDefinitionHolder> configCandidates = new ArrayList<>(); String[] candidateNames = registry.getBeanDefinitionNames(); //遍历之前注册的所有bean定义,找到其中的配置类,其实就是我们自己传进来的配置类 for (String beanName : candidateNames) { //...省略校验过程... BeanDefinition beanDef = registry.getBeanDefinition(beanName); //检查是否是有@Configuration注解的BeanDifinition -> full类型的配置类 -> 会把配置类替换成动态代理类 //或者该类包含@Component @ComponentScan @Import @ImportResource @Bean 注解的其中之一 -> lite类型的配置类 -> 不会替换成动态代理类 else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) { configCandidates.add(new BeanDefinitionHolder(beanDef, beanName)); } } //....省略片段.... //实例化一个配置类解析器 ConfigurationClassParser parser = new ConfigurationClassParser( this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry); do { //解析配置类 parser.parse(candidates); parser.validate(); //parser.getConfigurationClasses()就是拿到刚刚解析完放到map中的配置类 Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses()); configClasses.removeAll(alreadyParsed); //这里处理@Import导入的beanDefintion和配置类中的@Bean this.reader.loadBeanDefinitions(configClasses); alreadyParsed.addAll(configClasses); //以下逻辑是找出未解析的配置类,如@Bean和ImportBeanDefinitionRegistrar所引入的 candidates.clear(); if (registry.getBeanDefinitionCount() > candidateNames.length) { String[] newCandidateNames = registry.getBeanDefinitionNames(); 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) { if (!oldCandidateNames.contains(candidateName)) { BeanDefinition bd = registry.getBeanDefinition(candidateName); //将是配置类并且没有解析过的BeanDefinition放到候选集合中继续解析 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) && !alreadyParsedClasses.contains(bd.getBeanClassName())) { candidates.add(new BeanDefinitionHolder(bd, candidateName)); } } } candidateNames = newCandidateNames; } } while (!candidates.isEmpty()); }
ConfigurationClassUtils.checkConfigurationClassCandidate中的摘取片段
//检查是否有标识@Configuration Map<String, Object> config = metadata.getAnnotationAttributes(Configuration.class.getName()); if (config != null && !Boolean.FALSE.equals(config.get("proxyBeanMethods"))) { //设置配置属性值为full beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_FULL); } //检查是否包含@Component @ComponentScan @Import @ImportResource @Bean else if (config != null || isConfigurationCandidate(metadata)) { //设置配置属性值为lite beanDef.setAttribute(CONFIGURATION_CLASS_ATTRIBUTE, CONFIGURATION_CLASS_LITE); } else { return false; }
配置类解析流程(parser.parse(candidates))
public void parse(Set<BeanDefinitionHolder> configCandidates) { for (BeanDefinitionHolder holder : configCandidates) { BeanDefinition bd = holder.getBeanDefinition(); //配置类的beanDefinition为AnnotatedGenericBeanDefinition,true if (bd instanceof AnnotatedBeanDefinition) { //传入配置类的元数据与beanName parse(((AnnotatedBeanDefinition) bd).getMetadata(), holder.getBeanName()); } } } protected final void parse(AnnotationMetadata metadata, String beanName) throws IOException { processConfigurationClass(new ConfigurationClass(metadata, beanName), DEFAULT_EXCLUSION_FILTER); }
processConfigurationClass
protected void processConfigurationClass(ConfigurationClass configClass, Predicate<String> filter) throws IOException { SourceClass sourceClass = asSourceClass(configClass, filter); do { //解析配置类,这里可能返回配置类的父类,需要继续处理 sourceClass = doProcessConfigurationClass(configClass, sourceClass, filter); } while (sourceClass != null); //将配置类放入map中 this.configurationClasses.put(configClass, configClass); }
doProcessConfigurationClass
//@Configuration 本身也是 @Component的组合注解 if (configClass.getMetadata().isAnnotated(Component.class.getName())) { // 处理内置类,如果内置类也是个配置类,递归处理内置类 processMemberClasses(configClass, sourceClass, filter); }
处理@ComponentScan
// Process any @ComponentScan annotations // 找出配置类上的@ComponentScan注解属性 Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable( sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class); for (AnnotationAttributes componentScan : componentScans) { //将@ComponentScan引入的所有类扫描成BeanDefinition并注册到容器中 Set<BeanDefinitionHolder> scannedBeanDefinitions = this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName()); //这里循环是为了判断扫描出来的beanDefinition是否是配置类,如果是配置类的话需要递归解析 for (BeanDefinitionHolder holder : scannedBeanDefinitions) { BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition(); //这里是必然为true, 能被扫描出来的必然有@Component注解,而@Component注解为lite配置类 //这里主要是为了在检查的同时设置一下full或者lite的类型 if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) { //配置类就继续递归解析 parse(bdCand.getBeanClassName(), holder.getBeanName()); } } }
this.componentScanParser.parse
public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) { //重新new了一个classpath的bean定义扫描器,没用我们最开始创建的 // 这里添加了一个默认的过滤器,过滤@Component注解的 ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader); //添加自己配置的过滤器 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); } } //如果配置的为懒加载,则扫描出来的所有BeanDefinition都默认为懒加载的 boolean lazyInit = componentScan.getBoolean("lazyInit"); if (lazyInit) { scanner.getBeanDefinitionDefaults().setLazyInit(true); } //将配置的basePackages中所有的包路径放到set集合中,保证最终所有的包路径唯一 Set<String> basePackages = new LinkedHashSet<>(); String[] basePackagesArray = componentScan.getStringArray("basePackages"); for (String pkg : basePackagesArray) { String[] tokenized = StringUtils.tokenizeToStringArray(this.environment.resolvePlaceholders(pkg), ConfigurableApplicationContext.CONFIG_LOCATION_DELIMITERS); Collections.addAll(basePackages, tokenized); } //添加一个排除过滤器,排除该配置类 scanner.addExcludeFilter(new AbstractTypeHierarchyTraversingFilter(false, false) { @Override protected boolean matchClassName(String className) { return declaringClass.equals(className); } }); //开始扫描 return scanner.doScan(StringUtils.toStringArray(basePackages)); }
doScan
protected Set<BeanDefinitionHolder> doScan(String... basePackages) { Assert.notEmpty(basePackages, "At least one base package must be specified"); Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>(); for (String basePackage : basePackages) { //找到所有候选的bean -> 默认过滤器为过滤标识了@Component注解的class Set<BeanDefinition> candidates = findCandidateComponents(basePackage); for (BeanDefinition candidate : candidates) { String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry); if (candidate instanceof AbstractBeanDefinition) { //设置默认值,比如上一个方法刚刚设置的是否懒加载 postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName); } if (candidate instanceof AnnotatedBeanDefinition) { //解析beanClass的所有注解填充到beanDefinition中,@Lazy @Primary @DependsOn @Role @Description AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate); } //检查之前是否注册过,未注册返回true if (checkCandidate(beanName, candidate)) { BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName); beanDefinitions.add(definitionHolder); //将beanDefinition注册到容器中 registerBeanDefinition(definitionHolder, this.registry); } } } return beanDefinitions; }
寻找候选组件#findCandidateComponents
public Set<BeanDefinition> findCandidateComponents(String basePackage) { return scanCandidateComponents(basePackage); }
private Set<BeanDefinition> scanCandidateComponents(String basePackage) { Set<BeanDefinition> candidates = new LinkedHashSet<>(); //将类路径替换成绝对路径 String packageSearchPath = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX + resolveBasePackage(basePackage) + '/' + this.resourcePattern; //找出该路径下的所有类资源 Resource[] resources = getResourcePatternResolver().getResources(packageSearchPath); for (Resource resource : resources) { if (resource.isReadable()) { MetadataReader metadataReader = getMetadataReaderFactory().getMetadataReader(resource); //调用刚刚配置的过滤器进行匹配, //默认过滤器逻辑:是否标识了@Component注解(包括组合的,如@Service) if (isCandidateComponent(metadataReader)) { //通过扫描方式创建的BeanDefintion为ScannedGenericBeanDefinition ScannedGenericBeanDefinition sbd = new ScannedGenericBeanDefinition(metadataReader); sbd.setSource(resource); //不是接口和抽象类,或者是抽象类但标识了@Lookup if (isCandidateComponent(sbd)) { //将beanDefinition存到集合中 candidates.add(sbd); } } } } return candidates; }