Spring BeanFactoryPostProcessor加

2022-06-27  本文已影响0人  异或

加载入口

void refresh() {
...
    invokeBeanFactoryPostProcessors(beanFactory);
...
}

PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors

  1. 执行BeanDefinitionRegistryPostProcessor
// 1. CachingMetadataReaderFactoryPostProcessor 注入BeanDefinition
        private void register(BeanDefinitionRegistry registry) {
            BeanDefinition definition = BeanDefinitionBuilder
                    .genericBeanDefinition(SharedMetadataReaderFactoryBean.class, SharedMetadataReaderFactoryBean::new)
                    .getBeanDefinition();
            registry.registerBeanDefinition(BEAN_NAME, definition);
        }
  1. 第二次执行BeanDefinitionRegistryPostProcessor(实现PriorityOrdered接口的PostProcessor)
    主要作用是解析@CompentScan注解,扫描注解包下的类并为其生成BeanDefinition,缓存在BeanFactory类的beanDefinitionMap中
// 1. ConfigurationClassPostProcessor 注入BeanDefinition
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
        ...
        processConfigBeanDefinitions(registry);
    }
    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        ...
        Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
        Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
        do {
            parser.parse(candidates); // 调用ConfigurationClassParser.parse方法
            parser.validate();
        ...
        while (!candidates.isEmpty());
         ...
    public void parse(Set<BeanDefinitionHolder> configCandidates) {
        for (BeanDefinitionHolder holder : configCandidates) {
                    ...
                    parse(bd.getBeanClassName(), holder.getBeanName());  // 调用parse方法
                    ...
    }
    protected void processConfigurationClass(ConfigurationClass configClass) throws IOException {
        ...
        // Recursively process the configuration class and its superclass hierarchy.
        SourceClass sourceClass = asSourceClass(configClass);
        do {
            sourceClass = doProcessConfigurationClass(configClass, sourceClass);
        }
        while (sourceClass != null);
        ...
    }
    // 对有@ Component @PropertySource @PropertySources @ComponentScan @Import @ImportResource @Bean注解的类 及其父类深度便利,生成BeanDefinition
    protected final SourceClass doProcessConfigurationClass(ConfigurationClass configClass, SourceClass sourceClass)
            throws IOException {

        if (configClass.getMetadata().isAnnotated(Component.class.getName())) {
            // Recursively process any member (nested) classes first
            processMemberClasses(configClass, sourceClass);
        }

        // Process any @PropertySource annotations
        for (AnnotationAttributes propertySource : AnnotationConfigUtils.attributesForRepeatable(
                sourceClass.getMetadata(), PropertySources.class,
                org.springframework.context.annotation.PropertySource.class)) {
            if (this.environment instanceof ConfigurableEnvironment) {
                processPropertySource(propertySource);
            }
            else {
                logger.info("Ignoring @PropertySource annotation on [" + sourceClass.getMetadata().getClassName() +
                        "]. Reason: Environment must implement ConfigurableEnvironment");
            }
        }

        // Process any @ComponentScan annotations
        Set<AnnotationAttributes> componentScans = AnnotationConfigUtils.attributesForRepeatable(
                sourceClass.getMetadata(), ComponentScans.class, ComponentScan.class);
        if (!componentScans.isEmpty() &&
                !this.conditionEvaluator.shouldSkip(sourceClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN)) {
            for (AnnotationAttributes componentScan : componentScans) {
                // The config class is annotated with @ComponentScan -> perform the scan immediately
                Set<BeanDefinitionHolder> scannedBeanDefinitions =
                        this.componentScanParser.parse(componentScan, sourceClass.getMetadata().getClassName());
                // Check the set of scanned definitions for any further config classes and parse recursively if needed
                for (BeanDefinitionHolder holder : scannedBeanDefinitions) {
                    BeanDefinition bdCand = holder.getBeanDefinition().getOriginatingBeanDefinition();
                    if (bdCand == null) {
                        bdCand = holder.getBeanDefinition();
                    }
                    if (ConfigurationClassUtils.checkConfigurationClassCandidate(bdCand, this.metadataReaderFactory)) {
                        parse(bdCand.getBeanClassName(), holder.getBeanName());
                    }
                }
            }
        }

        // Process any @Import annotations
        processImports(configClass, sourceClass, getImports(sourceClass), true);

        // Process any @ImportResource annotations
        AnnotationAttributes importResource =
                AnnotationConfigUtils.attributesFor(sourceClass.getMetadata(), ImportResource.class);
        if (importResource != null) {
            String[] resources = importResource.getStringArray("locations");
            Class<? extends BeanDefinitionReader> readerClass = importResource.getClass("reader");
            for (String resource : resources) {
                String resolvedResource = this.environment.resolveRequiredPlaceholders(resource);
                configClass.addImportedResource(resolvedResource, readerClass);
            }
        }

        // Process individual @Bean methods
        Set<MethodMetadata> beanMethods = retrieveBeanMethodMetadata(sourceClass);
        for (MethodMetadata methodMetadata : beanMethods) {
            configClass.addBeanMethod(new BeanMethod(methodMetadata, configClass));
        }

        // Process default methods on interfaces
        processInterfaces(configClass, sourceClass);

        // Process superclass, if any
        if (sourceClass.getMetadata().hasSuperClass()) {
            String superclass = sourceClass.getMetadata().getSuperClassName();
            if (superclass != null && !superclass.startsWith("java") &&
                    !this.knownSuperclasses.containsKey(superclass)) {
                this.knownSuperclasses.put(superclass, configClass);
                // Superclass found, return its annotation metadata and recurse
                return sourceClass.getSuperClass();
            }
        }

        // No superclass -> processing is complete
        return null;
    }
  1. 第三次执行BeanDefinitionRegistryPostProcessor(实现Ordered接口的PostProcessor)
ConfigPropertySourcesProcessor // apollo会在此处注入ApolloAnnotationProcessor
  public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) throws BeansException {
    Map<String, Object> propertySourcesPlaceholderPropertyValues = new HashMap<>();
    // to make sure the default PropertySourcesPlaceholderConfigurer's priority is higher than PropertyPlaceholderConfigurer
    propertySourcesPlaceholderPropertyValues.put("order", 0);

    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, PropertySourcesPlaceholderConfigurer.class.getName(),
        PropertySourcesPlaceholderConfigurer.class, propertySourcesPlaceholderPropertyValues);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloAnnotationProcessor.class.getName(),
        ApolloAnnotationProcessor.class);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, SpringValueProcessor.class.getName(), SpringValueProcessor.class);
    BeanRegistrationUtil.registerBeanDefinitionIfNotExists(registry, ApolloJsonValueProcessor.class.getName(),
        ApolloJsonValueProcessor.class);

    processSpringValueDefinition(registry);
  }
  1. 第四次执行BeanDefinitionRegistryPostProcessor
1. // zebra - ZebraMapperScannerConfigurer
2. // mybatis - MapperScannerConfigurer 
3. // dubbo - ServiceAnnotationBeanPostProcessor // 注入@Service注解的BeanDefinition(注入两次)
    private void registerServiceBeans(Set<String> packagesToScan, BeanDefinitionRegistry registry) {

        DubboClassPathBeanDefinitionScanner scanner =
                new DubboClassPathBeanDefinitionScanner(registry, environment, resourceLoader);
        BeanNameGenerator beanNameGenerator = resolveBeanNameGenerator(registry);
        scanner.setBeanNameGenerator(beanNameGenerator);
        scanner.addIncludeFilter(new AnnotationTypeFilter(Service.class));
        for (String packageToScan : packagesToScan) {
            scanner.scan(packageToScan); // 注入@Service注解的BeanDefinition
            Set<BeanDefinitionHolder> beanDefinitionHolders =
                    findServiceBeanDefinitionHolders(scanner, packageToScan, registry, beanNameGenerator);
            if (!CollectionUtils.isEmpty(beanDefinitionHolders)) {
                for (BeanDefinitionHolder beanDefinitionHolder : beanDefinitionHolders) {
                    registerServiceBean(beanDefinitionHolder, registry, scanner); // 再次注入
                }
                ...

    private void registerServiceBean(BeanDefinitionHolder beanDefinitionHolder, BeanDefinitionRegistry registry,
                                     DubboClassPathBeanDefinitionScanner scanner) {

        Class<?> beanClass = resolveClass(beanDefinitionHolder);
        Service service = findAnnotation(beanClass, Service.class);
        Class<?> interfaceClass = resolveServiceInterfaceClass(beanClass, service);
        String annotatedServiceBeanName = beanDefinitionHolder.getBeanName();
        AbstractBeanDefinition serviceBeanDefinition =
                buildServiceBeanDefinition(service, interfaceClass, annotatedServiceBeanName);
        // ServiceBean:couponQueryApiImpl:xxx.xxxx.xxx:1.0.0:ykq-c-marketing
        String beanName = generateServiceBeanName(service, interfaceClass, annotatedServiceBeanName);
        if (scanner.checkCandidate(beanName, serviceBeanDefinition)) { 
            registry.registerBeanDefinition(beanName, serviceBeanDefinition);
          ...
  1. 执行invokeBeanFactoryPostProcessors // 实现BeanDefinitionRegistryPostProcessor;多数BeanDefinitionRegistryPostProcessor该方法为空
  2. 再次执行invokeBeanFactoryPostProcessors // 区别前5步,此处的BeanPostProcessor不需要实现BeanDefinitionRegistryPostProcessor,执行顺序同RegistryPostProcessor,先执行实现PriorityOrdered、在执行实现Ordered、最后执行剩余所有的BeanFactoryPostProcessor
上一篇 下一篇

猜你喜欢

热点阅读