BeanDefinitionReader的工作原理

文章详细描述了一个Spring框架中的类ConfigurationClassBeanDefinitionReader,它负责根据@Condition注解和导入的配置类,动态决定哪些Bean应该被注册。过程包括检查条件、处理导入类的依赖关系和应用Bean注解配置。
class ConfigurationClassBeanDefinitionReader {
    // 加载BD
    public void loadBeanDefinitions(Set<ConfigurationClass> configurationModel) {
        // 创建一个Condition条件计算器
        TrackedConditionEvaluator trackedConditionEvaluator = new TrackedConditionEvaluator();
        // 遍历所有的配置类
        for (ConfigurationClass configClass : configurationModel) {
            // 从配置类中加载BD
            loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator) {
                // 根据条件@Condition注解来判断是否符合成为@Bean的条件
                if (trackedConditionEvaluator.shouldSkip(configClass) {
                    // 获取当前配置类是不是标记了被跳过
                    Boolean skip = this.skipped.get(configClass);
                    // 如果没有被标记
                    if (skip == null) {
                        // 判断当前配置类是不是导入的
                        if (configClass.isImported()) {
                            boolean allSkipped = true;
                            // 获取导入当前类的所有配置类
                            for (ConfigurationClass importedBy : configClass.getImportedBy()) {
                                // 递归校验,校验导入当前类的配置类是否需要被跳过
                                // 意思就是有N个类导入当前类,只有所有的类的都被跳过,则当前被导入的类也要被跳过
                                // 因为导入当前类的所有类都不符合条件,所以当前类也没办法成为Bean
                                // 但是只要有一个导入的Bean是不需要被跳过,则当前配置类就有用
                                if (!shouldSkip(importedBy)) {
                                    // 如果有一个不需要被跳过,标识不是所有的都需要被跳过
                                    allSkipped = false;
                                    break;
                                }
                            }
                            // 如果被导入当前类的所有配置类都被跳过了,那么当前配置类也会被跳过
                            if (allSkipped) {
                                skip = true;
                            }
                        }
                        // 如果上面没有标记当前类需要被跳过
                        // 那么再次使用Condition注解计算器计算当前配置类是否需要被跳过
                        if (skip == null) {
                            skip = conditionEvaluator.shouldSkip(configClass.getMetadata(), ConfigurationPhase.REGISTER_BEAN);
                        }
                        // 保存当前配置类是否需要被跳过
                        this.skipped.put(configClass, skip);
                    }
                    return skip;
                }){
                    // 如果满足条件,需要被跳过
                    // 获取BeanName
                    String beanName = configClass.getBeanName();
                    // 如果当前容器中存在该Bean,要移除
                    if (StringUtils.hasLength(beanName) && this.registry.containsBeanDefinition(beanName)) {
                        this.registry.removeBeanDefinition(beanName);
                    }
                    // 导入的Bean信息也需要移除
                    this.importRegistry.removeImportingClass(configClass.getMetadata().getClassName());
                    return;
                }
                // 如果不需要被跳过,获取当前类是不是导入的
                if (configClass.isImported()) {
                    // 从导入的配置类中注册BD
                    registerBeanDefinitionForImportedConfigurationClass(configClass) {
                        // 获取配置类的元信息
                        AnnotationMetadata metadata = configClass.getMetadata();
                        // 创建BD
                        AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata);
                        // 解析Scope的元信息
                        ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef) {
                            // 创建作用域元数据
                            ScopeMetadata metadata = new ScopeMetadata();
                            // 如果是抽象的BD
                            if (definition instanceof AnnotatedBeanDefinition) {
                                AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
                                // 获取Scope注解信息
                                // 	protected Class<? extends Annotation> scopeAnnotationType = Scope.class;
                                AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(annDef.getMetadata(), this.scopeAnnotationType);
                                // 如果存在@Scope注解信息
                                if (attributes != null) {
                                    // 设置作用域名称
                                    metadata.setScopeName(attributes.getString("value"));
                                    // 获取代理模式
                                    ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
                                    // 是否是默认的代理模式
                                    if (proxyMode == ScopedProxyMode.DEFAULT) {
                                        proxyMode = this.defaultProxyMode;
                                    }
                                    // 设置代理模式
                                    metadata.setScopedProxyMode(proxyMode);
                                }
                            }
                            return metadata;
                        }
                        // 设置作用域
                        configBeanDef.setScope(scopeMetadata.getScopeName());
                        // 生成配置类的beanname
                        String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
                        // 处理@Lazy,@Primary公共的一些注解信息
                        AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
                        // 获取BD的持有者
                        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
                        // 判断当前Scope的元数据中,是不是设置了
                        definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry){
                            // 获取元素据中设置的代理模式
                            ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();
                            // 如果是默认值,没有设置需要代理
                            if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
                                // 直接返回
                                return definition;
                            }
                            // 如果需要设置代理,获取是否使用CGLIB代理
                            boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);
                            // 创建代理的BD
                            return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass){
                                // 获取BeanName
                                String originalBeanName = definition.getBeanName();
                                // 获取BD
                                BeanDefinition targetDefinition = definition.getBeanDefinition();
                                // 获取目标的BeanName
                                // String TARGET_NAME_PREFIX = "scopedTarget.";
                                String targetBeanName = getTargetBeanName(originalBeanName){
                                    return TARGET_NAME_PREFIX + originalBeanName;
                                }
                                // 创建一个生成Scoped代理的FactoryBean的BD,用于创建Scope的代理对象
                                RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
                                proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
                                proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
                                proxyDefinition.setSource(definition.getSource());
                                proxyDefinition.setRole(targetDefinition.getRole());
                                // 给ScopedProxyFactoryBean对象设置属性targetBeanName值
                                proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);
                                // 设置使用CGLIB标识
                                if (proxyTargetClass) {
                                    targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
                                }
                                else {
                                    // 给ScopedProxyFactoryBean对象设置属性proxyTargetClass值
                                    proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
                                }
                                // 从原始BD中获取自动注入的方式
                                proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
                                proxyDefinition.setPrimary(targetDefinition.isPrimary());
                                if (targetDefinition instanceof AbstractBeanDefinition) {
                                    proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
                                }

                                // 忽略目标bean,使用作用域代理.
                                targetDefinition.setAutowireCandidate(false);
                                targetDefinition.setPrimary(false);

                                // 注册目标Bean的定义信息
                                registry.registerBeanDefinition(targetBeanName, targetDefinition);
                                // 返回作用域代理的BD
                                return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
                            }
                        }
                        // 注册BD
                        this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
                        // 设置给Bean设置BeanName
                        configClass.setBeanName(configBeanName);

                    }
                }
                // 遍历所有的@Bean方法
                for (BeanMethod beanMethod : configClass.getBeanMethods()) {
                    // 从@Bean方法中加载BD
                    loadBeanDefinitionsForBeanMethod(beanMethod){
                        // 获取配置类信息
                        ConfigurationClass configClass = beanMethod.getConfigurationClass();
                        // 获取@bean方法的元数据
                        MethodMetadata metadata = beanMethod.getMetadata();
                        // 获取方法名
                        String methodName = metadata.getMethodName();
                        // 使用条件计算器是否需要跳过
                        // 是否符合Conditional注解条件
                        if (this.conditionEvaluator.shouldSkip(metadata, ConfigurationPhase.REGISTER_BEAN)) {
                            // 如果需要跳过,缓存需要跳过的@bean方法
                            configClass.skippedBeanMethods.add(methodName);
                            return;
                        }
                        // 如果该方法被缓存为跳过,则不处理
                        if (configClass.skippedBeanMethods.contains(methodName)) {
                            return;
                        }
                        // 获取@Bean注解信息
                        AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
                        // 获取bean的名称
                        List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
                        // 取第一个名称作为BeanName,否则使用方法名作为BeanName
                        String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
                        // 注册Bean别名
                        for (String alias : names) {
                            this.registry.registerAlias(beanName, alias);
                        }
                        // 判断存在BeanName重复,重复定义BeanName抛出异常
                        if (isOverriddenByExistingDefinition(beanMethod, beanName)) {
                            if (beanName.equals(beanMethod.getConfigurationClass().getBeanName())) {
                                throw new BeanDefinitionStoreException(beanMethod.getConfigurationClass().getResource().getDescription());
                            }
                            return;
                        }
                        // 创建ConfigurationClassBeanDefinition的BD
                        ConfigurationClassBeanDefinition beanDef = new ConfigurationClassBeanDefinition(configClass, metadata);
                        // 设置该配置类的资源信息
                        beanDef.setResource(configClass.getResource());
                        // 设置方法的元信息
                        beanDef.setSource(this.sourceExtractor.extractSource(metadata, configClass.getResource()));
                        // 如果方法是静态的
                        if (metadata.isStatic()) {
                            // 如果是标准的注解元信息对象,设置BeanName
                            if (configClass.getMetadata() instanceof StandardAnnotationMetadata) {
                                beanDef.setBeanClass(((StandardAnnotationMetadata) configClass.getMetadata()).getIntrospectedClass());
                            }
                            // 如果不是,则设置ClassName
                            else {
                                beanDef.setBeanClassName(configClass.getMetadata().getClassName());
                            }
                            // 设置唯一的工厂方法名称为方法名
                            beanDef.setUniqueFactoryMethodName(methodName);
                        }
                        else {
                            // 实例方法@Bean
                            // 设置工厂Bean的名称为BeanName
                            beanDef.setFactoryBeanName(configClass.getBeanName());
                            // 设置唯一的工厂方法名称为方法名
                            beanDef.setUniqueFactoryMethodName(methodName);
                        }
                        // 设置解析后的方法对象
                        if (metadata instanceof StandardMethodMetadata) {
                            beanDef.setResolvedFactoryMethod(((StandardMethodMetadata) metadata).getIntrospectedMethod());
                        }
                        // 设置注入方式,使用构造注入
                        beanDef.setAutowireMode(AbstractBeanDefinition.AUTOWIRE_CONSTRUCTOR);
                        beanDef.setAttribute(org.springframework.beans.factory.annotation.RequiredAnnotationBeanPostProcessor.SKIP_REQUIRED_CHECK_ATTRIBUTE, Boolean.TRUE);
                        // 设置公共的注解信息,例如@Lazy,@Primary
                        AnnotationConfigUtils.processCommonDefinitionAnnotations(beanDef, metadata);
                        // 获取@Bean设置的注入方式
                        Autowire autowire = bean.getEnum("autowire");
                        if (autowire.isAutowire()) {
                            beanDef.setAutowireMode(autowire.value());
                        }
                        boolean autowireCandidate = bean.getBoolean("autowireCandidate");
                        if (!autowireCandidate) {
                            beanDef.setAutowireCandidate(false);
                        }
                        // 设置初始化方法
                        String initMethodName = bean.getString("initMethod");
                        if (StringUtils.hasText(initMethodName)) {
                            beanDef.setInitMethodName(initMethodName);
                        }
                        // 设置销毁方法
                        String destroyMethodName = bean.getString("destroyMethod");
                        beanDef.setDestroyMethodName(destroyMethodName);

                        // 设置作用域代理,创建新的代理BD,如果有必要,上面有讲过
                        ScopedProxyMode proxyMode = ScopedProxyMode.NO;
                        AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(metadata, Scope.class);
                        if (attributes != null) {
                            beanDef.setScope(attributes.getString("value"));
                            proxyMode = attributes.getEnum("proxyMode");
                            if (proxyMode == ScopedProxyMode.DEFAULT) {
                                proxyMode = ScopedProxyMode.NO;
                            }
                        }
                        BeanDefinition beanDefToRegister = beanDef;
                        if (proxyMode != ScopedProxyMode.NO) {
                            BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
                            beanDefToRegister = new ConfigurationClassBeanDefinition((RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
                        }
                        // 注册BD
                        this.registry.registerBeanDefinition(beanName, beanDefToRegister);
                    }
                }
                // 从导入的XML中获取BD
                loadBeanDefinitionsFromImportedResources(configClass.getImportedResources()){
                    // 缓存BeanDefinitionReader
                    Map<Class<?>, BeanDefinitionReader> readerInstanceCache = new HashMap<>();
                    // 遍历所有的资源文件
                    importedResources.forEach((resource, readerClass) -> {
                        // 是否设置了指定的BeanDefinitionReader
                        if (BeanDefinitionReader.class == readerClass) {
                            // 导入的是.groovy配置文件
                            if (StringUtils.endsWithIgnoreCase(resource, ".groovy")) {
                                readerClass = GroovyBeanDefinitionReader.class;
                            }
                            else {
                                // 主要是“.xml”文件,但也适用于任何其他扩展名
                                readerClass = XmlBeanDefinitionReader.class;
                            }
                        }
                        // 是否缓存了这个类型的BeanDefinitionReader
                        BeanDefinitionReader reader = readerInstanceCache.get(readerClass);
                        // 如果没有缓存
                        if (reader == null) {
                            // 实例化指定的BeanDefinitionReader
                            reader = readerClass.getConstructor(BeanDefinitionRegistry.class).newInstance(this.registry);
                            // 如果可能的话,将当前的ResourceLoader和环境对象给它
                            if (reader instanceof AbstractBeanDefinitionReader) {
                                AbstractBeanDefinitionReader abdr = ((AbstractBeanDefinitionReader) reader);
                                abdr.setResourceLoader(this.resourceLoader);
                                abdr.setEnvironment(this.environment);
                            }
                            // 缓存BeanDefinitionReader
                            readerInstanceCache.put(readerClass, reader);
                        }
                        // 使用对应的BeanDefinitionReader加载配置
                        reader.loadBeanDefinitions(resource){
                            return loadBeanDefinitions(location, null){
                                // 获取资源加载器
                                ResourceLoader resourceLoader = getResourceLoader();
                                // 如果资源加载器是ResourcePatternResolver类型,使用ResourcePatternResolver加载
                                if (resourceLoader instanceof ResourcePatternResolver) {
                                    // 获取到所有的配置文件
                                    Resource[] resources = ((ResourcePatternResolver) resourceLoader).getResources(location);
                                    // 从该配置文件中加载BD
                                    int count = loadBeanDefinitions(resources){
                                        // 记录加载的数量
                                        int count = 0;
                                        // 遍历所有的资源文件
                                        for (Resource resource : resources) {
                                            // 开始加载BD
                                            count += loadBeanDefinitions(resource){
                                                return loadBeanDefinitions(new EncodedResource(resource)){
                                                    // 获取InputStream
                                                    InputStream inputStream = encodedResource.getResource().getInputStream();
                                                    // 正式加载
                                                    return doLoadBeanDefinitions(inputSource, encodedResource.getResource()){
                                                        // 解析XML文件
                                                        Document doc = doLoadDocument(inputSource, resource);
                                                        // 注册BD
                                                        int count = registerBeanDefinitions(doc, resource);
                                                    }
                                                }
                                            }
                                        }
                                        return count;
                                    }
                                    return count;
                                }
                                else {
                                    // 和上面的逻辑是一样的,只是获取资源Resource的方式不一样
                                    Resource resource = resourceLoader.getResource(location);
                                    int count = loadBeanDefinitions(resource);
                                    return count;
                                }
                            }
                        }
                    });
                }
                loadBeanDefinitionsFromRegistrars(configClass.getImportBeanDefinitionRegistrars()){
                    // 遍历所有保存到配置类中的ImportBeanDefinitionRegistrar
                    // 回调registerBeanDefinitions方法,将指定的BD注册进去
                    registrars.forEach((registrar, metadata) -> registrar.registerBeanDefinitions(metadata, this.registry, this.importBeanNameGenerator));
                }
            }
        }
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值