Spring中@Scope注解的处理原理

public @interface Scope {

    @AliasFor("scopeName")
    String value() default "";

    @AliasFor("value")
    String scopeName() default "";

    // scoped代理的模式
    ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT {
        // 默认值: 只关注@ComponentScan(scopedProxy = ScopedProxyMode.TARGET_CLASS)
        // ComponentScan中的scopedProxy值决定它的值,如果没有,就为NO
        DEFAULT;
        // 不对Scope对象进行代理
        NO;
        // 对Scope对象进行JDK代理
        INTERFACES;
        // 对Scope对象进行CGLIB代理
        TARGET_CLASS;
    }
}
// 因为能标注@Scope注解的地方一个是在类上,一个实在@Bean的方法上

// 第一处,标注在类上,解析ComponentScan的时候会触发@Scope的解析或代理
class ComponentScanAnnotationParser {
    public Set<BeanDefinitionHolder> parse(AnnotationAttributes componentScan, final String declaringClass) {
        // 创建类路径Bean的扫描器
        ClassPathBeanDefinitionScanner scanner = new ClassPathBeanDefinitionScanner(this.registry, componentScan.getBoolean("useDefaultFilters"), this.environment, this.resourceLoader);
        // 获取注解的beanName生成器
        Class<? extends BeanNameGenerator> generatorClass = componentScan.getClass("nameGenerator");
        boolean useInheritedGenerator = (BeanNameGenerator.class == generatorClass);
        scanner.setBeanNameGenerator(useInheritedGenerator ? this.beanNameGenerator : BeanUtils.instantiateClass(generatorClass));
        // 获取对@Scope类的代理方式
        ScopedProxyMode scopedProxyMode = componentScan.getEnum("scopedProxy");
        // 获取如果在ComponentScan设置了scopedProxy对@Scope类的代理方式
        if (scopedProxyMode != ScopedProxyMode.DEFAULT) {
            // 将该值保存到扫描器中,到时候需要设置到BD中
            scanner.setScopedProxyMode(scopedProxyMode) {
                // 创建对应的Scope解析器,并且将@ComponentScan中配置的代理方法设置到解析器defaultProxyMode中
                this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(scopedProxyMode) {
                   this.defaultProxyMode =defaultProxyMode;
                }
            }
        } else {
            // 如果为默认值,就使用Scope解析器去解析
            Class<? extends ScopeMetadataResolver> resolverClass = componentScan.getClass("scopeResolver");
            // 设置指定的Scope类解析器
            scanner.setScopeMetadataResolver(BeanUtils.instantiateClass(resolverClass));
        }
        // 保存扫描的类是否是懒加载
        boolean lazyInit = componentScan.getBoolean("lazyInit");
        if (lazyInit) {
            // 	private BeanDefinitionDefaults beanDefinitionDefaults = new BeanDefinitionDefaults();
            scanner.getBeanDefinitionDefaults() {
                // 该类BeanDefinitionDefaults保存了默认的信息
                private Boolean lazyInit;
                private int autowireMode = AbstractBeanDefinition.AUTOWIRE_NO;
                private int dependencyCheck = AbstractBeanDefinition.DEPENDENCY_CHECK_NONE;
                private String initMethodName;
                private String destroyMethodName;
            }
             .setLazyInit(true);
        }
        // 获取扫描的包
        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);
        }
        for (Class<?> clazz : componentScan.getClassArray("basePackageClasses")) {
            basePackages.add(ClassUtils.getPackageName(clazz));
        }
        // 使用正在解析的类的包名作为扫描路径
        if (basePackages.isEmpty()) {
            basePackages.add(ClassUtils.getPackageName(declaringClass));
        }
        // 开始扫描
        return scanner.doScan(StringUtils.toStringArray(basePackages)) {
            Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();
            // 遍历所有需要扫描的包名
            for (String basePackage : basePackages) {
                // 扫描路径下的所有Bean的定义信息
                Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
                // 遍历所有的BD
                for (BeanDefinition candidate : candidates) {
                    // 解析Bean的Scope信息
                    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate) {
                        // 创建元数据对象
                        ScopeMetadata metadata = new ScopeMetadata() {
                            // 默认的作用域是单例
                            private String scopeName = BeanDefinition.SCOPE_SINGLETON;
                            // 默认的代理模式是不代理
                            private ScopedProxyMode scopedProxyMode = ScopedProxyMode.NO;
                        }
                        // 如果是注解的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);
                            // 如果存在
                            if (attributes != null) {
                                // 设置注解中配置的作用域
                                metadata.setScopeName(attributes.getString("value"));
                                // 获取注解中的代理模式
                                ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
                                // 如果注解的代理模式为默认值,表示没有填写代理模式
                                if (proxyMode == ScopedProxyMode.DEFAULT) {
                                    // 将该默认的代理模式给它
                                    // 默认的代理模式在上面
                                    // scanner.setScopedProxyMode(scopedProxyMode) {
                                    //     // 创建对应的Scope解析器,并且将@ComponentScan中配置的代理方法设置到解析器defaultProxyMode中
                                    //     this.scopeMetadataResolver = new AnnotationScopeMetadataResolver(scopedProxyMode) {
                                    //         this.defaultProxyMode =defaultProxyMode;
                                    //     }
                                    // }
                                    // 这个就是@ComponentScan配置的值,如果@ComponentScan没有配置,默认为NO
                                    proxyMode = this.defaultProxyMode;
                                }
                                // 将代理模式保存到Scope代理的元数据中
                                metadata.setScopedProxyMode(proxyMode);
                            }
                        }
                        return metadata;
                    }
                    // 给解析到的Scope注解信息设置到目标BD中
                    candidate.setScope(scopeMetadata.getScopeName());
                    // 生成beanName
                    String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
                    if (candidate instanceof AbstractBeanDefinition) {
                        postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName) {
                            // 将设置好的beanDefinitionDefaults默认值对象的值拷贝设置到BD中
                            // 因为上面使用beanDefinitionDefaults对象只处理了@ComponentScan获取lazyInit值
                            beanDefinition.applyDefaults(this.beanDefinitionDefaults) {
                                // 从defaluts对象中获取默认值,如果处理了,那么值就是处理后的值
                                // 设置的是@ComponentScan获取lazyInit值
                                Boolean lazyInit = defaults.getLazyInit();
                                if (lazyInit != null) {
                                    setLazyInit(lazyInit);
                                }
                                setAutowireMode(defaults.getAutowireMode());
                                setDependencyCheck(defaults.getDependencyCheck());
                                setInitMethodName(defaults.getInitMethodName());
                                setEnforceInitMethod(false);
                                setDestroyMethodName(defaults.getDestroyMethodName());
                                setEnforceDestroyMethod(false);
                            }
                            // 设置当前bean只能能注入指定的bean
                            if (this.autowireCandidatePatterns != null) {
                                beanDefinition.setAutowireCandidate(PatternMatchUtils.simpleMatch(this.autowireCandidatePatterns, beanName));
                            }
                        }
                    }
                    //如果是注解类型的BD
                    if (candidate instanceof AnnotatedBeanDefinition) {
                        // 执行公共注解设置
                        AnnotationConfigUtils.processCommonDefinitionAnnotations((AnnotatedBeanDefinition) candidate) {
                            // metadata就是当前类对应的反射元信息,也有可能传递指定的元信息对象
                            // 获取Lazy属性
                            AnnotationAttributes lazy = attributesFor(metadata, Lazy.class);
                            if (lazy != null) {
                                abd.setLazyInit(lazy.getBoolean("value"));
                            }
                            // 当当前类的元数据域传递的参数的元数据不一样,优先使用当前类对应的元数据信息
                            else if (abd.getMetadata() != metadata) {
                                lazy = attributesFor(abd.getMetadata(), Lazy.class);
                                if (lazy != null) {
                                    abd.setLazyInit(lazy.getBoolean("value"));
                                }
                            }
                            // 设置主要的注解信息
                            if (metadata.isAnnotated(Primary.class.getName())) {
                                abd.setPrimary(true);
                            }
                            // 设置依赖的bean的信息
                            AnnotationAttributes dependsOn = attributesFor(metadata, DependsOn.class);
                            if (dependsOn != null) {
                                abd.setDependsOn(dependsOn.getStringArray("value"));
                            }
                            // 设置bean的角色信息
                            AnnotationAttributes role = attributesFor(metadata, Role.class);
                            if (role != null) {
                                abd.setRole(role.getNumber("value").intValue());
                            }
                            // 设置bean的声明信息
                            AnnotationAttributes description = attributesFor(metadata, Description.class);
                            if (description != null) {
                                abd.setDescription(description.getString("value"));
                            }
                        }
                    }
                    // 校验beanName是否已经存在BD,并且与已存在的BD不兼容,就需要报错,就表示beanName重复了
                    if (checkCandidate(beanName, candidate)) {
                        // 创建BDH
                        BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                        // 根据scopeMetadata封装的Scope元信息,判断是否需要返回代理对象的BD
                        // 如果需要,返回代理对象的BD,不需要原样返回
                        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,也就是原始Bean的BeanName被替换了"scopedTarget."了
                            // String TARGET_NAME_PREFIX = "scopedTarget.";
                            String targetBeanName = getTargetBeanName(originalBeanName) {
                                return TARGET_NAME_PREFIX + originalBeanName;
                            }
                            // 创建一个生成Scoped代理的FactoryBean的BD,用于创建Scope的代理对象
                            // 真实的代理对象需要通过ScopedProxyFactoryBean来生成
                            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,使得目标bean不会被自动注入,那么根据类型,就可以使用到作用域代理.
                            targetDefinition.setAutowireCandidate(false);
                            // 并且让该原始对象不能成为主要的对象
                            targetDefinition.setPrimary(false);

                            // 注册目标Bean的定义信息,将需要被代理的Bean的beanName修改为scopedTarget.+beanName
                            registry.registerBeanDefinition(targetBeanName, targetDefinition);
                            // 返回作用域代理的BD,并将原始的BeanName作为ScopedProxyFactoryBean的BeanName
                            return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
                        }
                        }
                        // 保存需要注册的BD,可能是代理BD,也可能是原始BD
                        beanDefinitions.add(definitionHolder);
                        // 设置BD到Spring容器
                        registerBeanDefinition(definitionHolder, this.registry);
                    }
                }
            }
            return beanDefinitions;
        }
    }
}

// 第二次,处理ConfigClass配置类中,可能存在@Import导入的类中,可能在配置类的@Bean方法中
public class ConfigurationClassPostProcessor {
    public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
        // 创建配置类的解析器
        ConfigurationClassParser parser = new ConfigurationClassParser(this.metadataReaderFactory, this.problemReporter, this.environment, this.resourceLoader, this.componentScanBeanNameGenerator, registry);
        // 解析配置类,将所有配置类包装成BD
        parser.parse(candidates);
        // 上面解析的是配置类的@ComponentScan扫描的BD
        // 在使用配置类信息,因为配置类中还有@Bean,@Import导入的类,或者Registrars等等这些,它们的信息已经保存到配置类中,但是还未处理
        this.reader.loadBeanDefinitions(configClasses) {
            for (ConfigurationClass configClass : configClasses) {
                // 从配置类中
                loadBeanDefinitionsForConfigurationClass(configClass, trackedConditionEvaluator) {
                    // 如果当前类是导入的
                    if (configClass.isImported()) {
                        // 注入导入的Bean信息
                        registerBeanDefinitionForImportedConfigurationClass(configClass) {
                            // 获取导入的类的元数据信息
                            AnnotationMetadata metadata = configClass.getMetadata();
                            // 创建Bean,给BD设置导入的类名或者类对象
                            AnnotatedGenericBeanDefinition configBeanDef = new AnnotatedGenericBeanDefinition(metadata) {
                                if(metadata instanceof StandardAnnotationMetadata)

                                {
                                    setBeanClass(((StandardAnnotationMetadata) metadata).getIntrospectedClass());
                                }
                                else

                                {
                                    setBeanClassName(metadata.getClassName());
                                }
                                this.metadata =metadata;
                            }
                            // 解析当前BD的Scope注解信息,下面这些步骤和上面ComponentScanParse中处理这个注解的逻辑完全一样
                            // 就是解析@Scope注解信息
                            ScopeMetadata scopeMetadata = scopeMetadataResolver.resolveScopeMetadata(configBeanDef);
                            // 将代理模式设置到BD中
                            configBeanDef.setScope(scopeMetadata.getScopeName());
                            // 生成BeanName
                            String configBeanName = this.importBeanNameGenerator.generateBeanName(configBeanDef, this.registry);
                            // 处理公共BD注解信息,@Lazy,@Primary,将这些注解信息保存到BD中
                            AnnotationConfigUtils.processCommonDefinitionAnnotations(configBeanDef, metadata);
                            // 创建目标类的BD
                            BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(configBeanDef, configBeanName);
                            // 获取标识的代理模式,如果需要代理,则返回代理的BD,如果是代理BD,同时会将原始BD注册到Spring中
                            definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                            // 注册当前BD,可能是原始BD,也可能是代理BD
                            this.registry.registerBeanDefinition(definitionHolder.getBeanName(), definitionHolder.getBeanDefinition());
                            // 设置配置类的类名
                            configClass.setBeanName(configBeanName);
                        }
                    }
                    // 处理@Bean的方法
                    for (BeanMethod beanMethod : configClass.getBeanMethods()) {
                        loadBeanDefinitionsForBeanMethod(beanMethod) {
                            // 获取配置类信息
                            ConfigurationClass configClass = beanMethod.getConfigurationClass();
                            // 获取方法的元数据信息
                            MethodMetadata metadata = beanMethod.getMetadata();
                            // 获取方法名
                            String methodName = metadata.getMethodName();
                            // 获取Bean的注解信息
                            AnnotationAttributes bean = AnnotationConfigUtils.attributesFor(metadata, Bean.class);
                            // 获取Bean的名称
                            List<String> names = new ArrayList<>(Arrays.asList(bean.getStringArray("name")));
                            // 取出第一个作为beanName,剩下的作为别名注册
                            String beanName = (!names.isEmpty() ? names.remove(0) : methodName);
                            // 注册别名,即使被覆盖
                            for (String alias : names) {
                                this.registry.registerAlias(beanName, alias);
                            }
                            // 校验是否已经存在beanName对应的BD
                            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()) {
                                // 如果是标准的注解元信息对象,设置Class
                                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);
                            // 如果方法上面有@Scope注解
                            if (attributes != null) {
                                // 设置@Scope信息到BD中
                                beanDef.setScope(attributes.getString("value"));
                                proxyMode = attributes.getEnum("proxyMode");
                                // 如果为默认值,表示没有设置代理模式,则不需要代理
                                if (proxyMode == ScopedProxyMode.DEFAULT) {
                                    proxyMode = ScopedProxyMode.NO;
                                }
                            }
                            // 需要注册的BD,可能是代理BD,可能是原始BD
                            BeanDefinition beanDefToRegister = beanDef;
                            // 如果需要代理
                            if (proxyMode != ScopedProxyMode.NO) {
                                // 根据Scope的代理模式是否创建代理,上面有详细逻辑,如果产生了代理对象,还会将原始BD注册到Spring中
                                BeanDefinitionHolder proxyDef = ScopedProxyCreator.createScopedProxy(new BeanDefinitionHolder(beanDef, beanName), this.registry, proxyMode == ScopedProxyMode.TARGET_CLASS);
                                // 需要将代理的BD注解,
                                beanDefToRegister = new ConfigurationClassBeanDefinition((RootBeanDefinition) proxyDef.getBeanDefinition(), configClass, metadata);
                            }
                            // 注册BD
                            this.registry.registerBeanDefinition(beanName, beanDefToRegister);
                        }
                    }
                }
            }
        }
    }
}

// 在创建Scope代理的时候,就会将ScopedProxyFactoryBean的BD注册到Spring中
// 不清楚可以看上面的逻辑,扫描BD的时候就会将这些逻辑处理好
// 如果需要生成Scoped代理,使用ScopedProxyFactoryBean,所以需要将它注册为Bean
// 真实的代理对象需要通过ScopedProxyFactoryBean来生成
// RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
// // 给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);
// }
class ScopedProxyFactoryBean extends ProxyConfig implements FactoryBean<Object>, BeanFactoryAware, AopInfrastructureBean {
    // Bean的目标数据源对象
    private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource();
    // Bean的原始目标BeanName
    private String targetBeanName;
    // 新生成的代理对象
    private Object proxy;

    // 默认使用CBLIB
    public ScopedProxyFactoryBean() {
        setProxyTargetClass(true);
    }

    // BeanFactoryAware的回调,会在这个提前创建代理对象
    public void setBeanFactory(BeanFactory beanFactory) {
        // 给scopedTargetSource设置Bean工厂,因为需要获取目标Bean
        ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;
        this.scopedTargetSource.setBeanFactory(beanFactory);
        // 创建代理工厂生成代理类
        ProxyFactory pf = new ProxyFactory();
        pf.copyFrom(this);
        pf.setTargetSource(this.scopedTargetSource);
        // 获取目标类型
        Class<?> beanType = beanFactory.getType(this.targetBeanName);
        // 如果不是CBLIB代理,或者原始Bean是接口,或者是私有的,代理类将实现目标类的所有接口
        if (!isProxyTargetClass() || beanType.isInterface() || Modifier.isPrivate(beanType.getModifiers())) {
            pf.setInterfaces(ClassUtils.getAllInterfacesForClass(beanType, cbf.getBeanClassLoader()));
        }
        // 创建一个作用域对象,内部封装了对原始对象的操作
        ScopedObject scopedObject = new DefaultScopedObject(cbf, this.scopedTargetSource.getTargetBeanName());
        // 设置通知,这个通知为整个类切入的通知,切面也就是IntroductionAdvisor切面
        // 所以,会直接将ScopedObject这个接口直接切入到代理类中
        // 说白了,代理类实现了ScopedObject,并含有ScopedObject的功能,动态增强了一个类
        pf.addAdvice(new DelegatingIntroductionInterceptor(scopedObject));
        // 标记该类为AOP的Bean
        pf.addInterface(AopInfrastructureBean.class);
        // 获取代理对象
        this.proxy = pf.getProxy(cbf.getBeanClassLoader());
    }

    @Override
    public Object getObject() {
        // 调用这个一定是返回代理对象,如果没有创建代理对象报错
        if (this.proxy == null) {
            throw new FactoryBeanNotInitializedException();
        }
        return this.proxy;
    }

    // 获取代理对象的类型
    @Override
    public Class<?> getObjectType() {
        // 如果生成了代理对象,则获取代理对象的类型
        if (this.proxy != null) {
            return this.proxy.getClass();
        }
        // 如果没有生成代理对象,就获取目标类型,就是通过原始Bean的BeanName从Spirng中获取类型
        return this.scopedTargetSource.getTargetClass() {
            Class<?> targetClass = this.targetClass;
            if (targetClass != null) {
                return targetClass;
            }
            if (targetClass == null && this.beanFactory != null) {
                targetClass = this.beanFactory.getType(this.targetBeanName);
                if (targetClass == null) {
                    Object beanInstance = this.beanFactory.getBean(this.targetBeanName);
                    targetClass = beanInstance.getClass();
                }
                this.targetClass = targetClass;
            }
        }
    }

    public boolean isSingleton() {
        return true;
    }
}

// 创建Bean的过程中获取代理对象
public abstract class AbstractAutowireCapableBeanFactory extends AbstractBeanFactory {

    // 创建Bean,此时我们根据原始Bean的BeanName实际上创建的ScopedProxyFactoryBean的对象
    protected Object doCreateBean(final String beanName, final RootBeanDefinition mbd, final @Nullable Object[] args) {
        BeanWrapper instanceWrapper = null;
        // 如果是单例,先看一下类是否在factoryBean中缓存了
        if (mbd.isSingleton()) {
            instanceWrapper = this.factoryBeanInstanceCache.remove(beanName);
        }
        // 不是factoryBean
        if (instanceWrapper == null) {
            // 创建bean的实例
            instanceWrapper = createBeanInstance(beanName, mbd, args);
        }
        // 获取实例,此时这个Bean是ScopedProxyFactoryBean,因为该beanName实际上就是原始Bean的原始BeanName
        // 例如: scopeA需要代理,则scopeA就作为ScopedProxyFactoryBean,而scope原来的bean的beanName变成了scopedTarget.scopeA
        final Object bean = instanceWrapper.getWrappedInstance();
        // 获取实例类型
        Class<?> beanType = instanceWrapper.getWrappedClass();
        // 是否支持循环依赖
        // 不管真实的Bean是不是单例的,但是ScopedProxyFactoryBean它是单例的
        boolean earlySingletonExposure = (mbd.isSingleton() && this.allowCircularReferences && isSingletonCurrentlyInCreation(beanName));
        // 添加提前创建Bean的逻辑到三级缓存
        if (earlySingletonExposure) {
            addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));
        }
        Object exposedObject = bean;
        // ScopedProxyFactoryBean属性赋值
        populateBean(beanName, mbd, instanceWrapper);
        // 初始化类ScopedProxyFactoryBean
        exposedObject = initializeBean(beanName, exposedObject, mbd) {
            invokeAwareMethods(beanName, bean) {
                // ScopedProxyFactoryBean实现了BeanFactoryAware
                if (bean instanceof BeanFactoryAware) {
                    ((BeanFactoryAware) bean).setBeanFactory(AbstractAutowireCapableBeanFactory.this) {
                        // 到了ScopedProxyFactoryBean.setBeanFactory方法中,它已经将代理对象创建好了
                        // 详细代码可以看ScopedProxyFactoryBean.setBeanFactory
                    }
                }
            }
        }
        // 针对于Request,Session,Applicaion这三种作用于
        // 创建的Bean的时候会区分作用域
        if (mbd.isSingleton()) {
        } else if (mbd.isPrototype()) {
        } else {
            // 获取BD中存入的scope
            String scopeName = mbd.getScope();
            // 所有作用域信息对象
            // 在Context的postProcessBeanFactory方法中注册的
            // WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext){
            //     beanFactory.registerScope(WebApplicationContext.SCOPE_REQUEST, new RequestScope()){
            //         Scope previous = this.scopes.put(scopeName, scope);
            //     }
            //     beanFactory.registerScope(WebApplicationContext.SCOPE_SESSION, new SessionScope());
            //     if (servletContext != null) {
            //         beanFactory.registerScope(WebApplicationContext.SCOPE_APPLICATION, new ServletContextScope(servletContext));
            //     }
            }
            // 获取上面注册的注册过的作用域信息
            final Scope scope = this.scopes.get(scopeName);
            if (scope == null) {
                throw new IllegalStateException("No Scope registered for scope name '" + scopeName + "'");
            }
            // web作用域的对象主要存在与之对应的web作用域属性中
            // scope.get方法介绍
            Object scopedInstance = scope.get(beanName, () -> { return createBean(beanName, mbd, args)}){
                // 获取当前请求对象的所有属性
                RequestAttributes attributes = RequestContextHolder.currentRequestAttributes();
                // 获取beanName看一下是否存入的对象
                Object scopedObject = attributes.getAttribute(name, getScope());
                // 如果没有存入
                if (scopedObject == null) {
                    // 回调createBean方法objectFactory是上面传递进来的
                    scopedObject = objectFactory.getObject();
                    // 将创建好的对象保存到对应的作用域中
                    attributes.setAttribute(name, scopedObject, getScope());
                    // 再次检查一下,上面已经保存进去了,或者被其他线程保存进去了
                    Object retrievedObject = attributes.getAttribute(name, getScope());
                    // 如果存在
                    if (retrievedObject != null) {
                        // 我们将保存到作用域中的对象返回,可能是本身线程设置的,也可能是别的线程设置的,总之取第一个线程设置的值
                        scopedObject = retrievedObject;
                    }
                }
                return scopedObject;
            };
            // 从对象实例中获取Bean,也就是处理FactoryBean的情况,如果是FactoryBaen,从FactoryBean中获取,否原样返回
            bean = getObjectForBeanInstance(scopedInstance, name, beanName, mbd);
        }
    }
}

// 此时我们获取代理的Bean对象
@Configuration
@ComponentScan(value = "${base-package}", scopedProxy = ScopedProxyMode.TARGET_CLASS)
public class Demo {
    public static void main(String[] args) {
        AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(Demo.class);
        // @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE,proxyMode = ScopedProxyMode.TARGET_CLASS)
        // public class ScopeA {}
        ScopeA scopeA = context.getBean(ScopeA.class) {
            // 解析Bean
            return resolveBean(ResolvableType.forRawClass(requiredType), args, false) {
                // 解析beanName以及对应的Bean
                NamedBeanHolder<T> namedBean = resolveNamedBean(requiredType, args, nonUniqueAsNull) {
                    // 这里返回的就是目标的实际类型与FactoryBean中获取的类型两种类型的BeanName
                    // 获取ScopeA类型的所有beanName,这个就会有两个
                    // 一个是原始的Bean对象,beanName为"scopedTarget.scopeA"
                    // 一个是作用域代理的Bean,beanName为scopeA,其实他是一个FactoryBean
                    String[] candidateNames = getBeanNamesForType(requiredType) {
                        String[] resolvedBeanNames = =
                        doGetBeanNamesForType(ResolvableType.forRawClass(type), includeNonSingletons, true) {
                            List<String> result = new ArrayList<>();
                            // 检查所有bean定义
                            for (String beanName : this.beanDefinitionNames) {
                                // 获取BeanName对应的BD
                                RootBeanDefinition mbd = getMergedLocalBeanDefinition(beanName);
                                // 判断当前BeanName是不是一个FactoryBean
                                boolean isFactoryBean = isFactoryBean(beanName, mbd);
                                // 获取原始的的BD,只要代理BD才会有值
                                BeanDefinitionHolder dbd = mbd.getDecoratedDefinition();
                                // 是否匹配类型
                                boolean matchFound = false;
                                // 是否允许将FactoryBean初始化,默认为true,只要是单例的就行
                                boolean allowFactoryBeanInit = allowEagerInit || containsSingleton(beanName);
                                //原始对象不是Lazy加载
                                boolean isNonLazyDecorated = dbd != null && !mbd.isLazyInit();
                                // 如果不是FactoryBean类型
                                if (!isFactoryBean) {
                                    // includeNonSingletons传递的true
                                    // isSingleton: 当BD是代理BD的时候,返回代理BD是否是单例,如果是原始对象,判断原始BD是单例
                                    if (includeNonSingletons || isSingleton(beanName, mbd, dbd)) {
                                        // 进行类型匹配
                                        matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit) {
                                            // 解析BeanName,主要是去除&,没有就不去除
                                            String beanName = transformedBeanName(name);
                                            // 是否是FacotyBean的名称,以&开头
                                            boolean isFactoryDereference = BeanFactoryUtils.isFactoryDereference(name);
                                            // 获取实例
                                            Object beanInstance = getSingleton(beanName, false);
                                            if (beanInstance != null && beanInstance.getClass() != NullBean.class) {
                                                // 如果是FactoryBean
                                                if (beanInstance instanceof FactoryBean) {
                                                    // 还要判断beanName是不是&开头
                                                    // 如果不是
                                                    if (!isFactoryDereference) {
                                                        Class<?> type = getTypeForFactoryBean((FactoryBean<?>) beanInstance)
                                                        {
                                                            // 则需要调用factoryBean.getObjectType()方法,获取返回的类型
                                                            return factoryBean.getObjectType();
                                                        }
                                                        // 再使用给定的类型进行匹配
                                                        return (type != null && typeToMatch.isAssignableFrom(type));
                                                    }
                                                    // 如果是&开头,表示这是一个正常的FactoryBean
                                                    else {
                                                        // 因为beanInstance是去除&之后获取的Bean
                                                        // 所以存入的是实际上目标对象的实际类型,所以直接拿来匹配
                                                        return typeToMatch.isInstance(beanInstance);
                                                    }
                                                }
                                                // 如果不是FactoryBean,并且beanName不是以&开头
                                                else if (!isFactoryDereference) {
                                                    // 直接进行实例匹配
                                                    if (typeToMatch.isInstance(beanInstance)) {
                                                        return true;
                                                    }
                                                }
                                                return false;
                                            }
                                        }
                                    }
                                }
                                // 如果是factoryBean
                                else {
                                    // includeNonSingletons为true,原始对象不是懒加载,或者Bean是单例的
                                    if (includeNonSingletons || isNonLazyDecorated || (allowFactoryBeanInit && isSingleton(beanName, mbd, dbd))) {
                                        // 进行类型匹配,看上面代码详解
                                        matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                                    }
                                    // 如果未找到
                                    if (!matchFound) {
                                        // 添加&再找一遍
                                        // 因为正常提供的FactoryBean的BeanName是以&开头,但是作用于代理特殊,他是使用的原始的BeanName
                                        beanName = FACTORY_BEAN_PREFIX + beanName;
                                        // 再进行匹配,看上面代码详解
                                        matchFound = isTypeMatch(beanName, type, allowFactoryBeanInit);
                                    }
                                }
                                // 如果符合条件,保存
                                if (matchFound) {
                                    result.add(beanName);
                                }
                            }
                        }
                    }
                    // 如果存在多个
                    if (candidateNames.length > 1) {
                        // 需要自动注入的Bean
                        List<String> autowireCandidates = new ArrayList<>(candidateNames.length);
                        // 遍历所有的BeanName
                        for (String beanName : candidateNames) {
                            // 当前容器不包含beanName对应的BD,或者设置了自动注入的表示为true
                            // 对于scopeA,和scopedTarget.scopeA都是存在的,所以第一个条件不满足
                            // 第二个条件,在创建原始BD和代理BD的时候,特意将原始对象的autowireCandidate设置为了false
                            if (!containsBeanDefinition(beanName) || getBeanDefinition(beanName).isAutowireCandidate()) {
                                // 所以这里能进来的只有scopeA的个beanName,但是它实际上对应的是ScopedProxyFactoryBean的Bean
                                autowireCandidates.add(beanName);
                            }
                        }
                        // 如果存在需要注入的beanName
                        if (!autowireCandidates.isEmpty()) {
                            // 转为数组保存
                            candidateNames = StringUtils.toStringArray(autowireCandidates);
                        }
                    }
                    // 如果只有一个能注入的,直接返回,其他情况如果有多个可以注入,就要根据优先级,先判断是否是Primary,在根据Order接口的优先级来
                    if (candidateNames.length == 1) {
                        String beanName = candidateNames[0];
                        return new NamedBeanHolder<>(beanName,
                                // 根据beanName和给定需要获取的类型ScopeA类获取Bean
                                (T) getBean(beanName, requiredType.toClass() {
                                    return

                            doGetBean(name, requiredType, args, false) {
                                // 解析BeanName,为了去除&
                                final String beanName = transformedBeanName(name);
                                Object bean;
                                // 获取Bean的实例,如果是Scope作用域代理,获取的就是ScopedProxyFactoryBean
                                // 其他的就是实际对应的Bean
                                Object sharedInstance = getSingleton(beanName);
                                // 如果已经存在
                                if (sharedInstance != null && args == null) {
                                    // 从对象实例中获取对象,说白了就是从FactoryBean中获取实例
                                    // 如果不是FactoryBean,返回对象本身
                                    bean = getObjectForBeanInstance(sharedInstance, name, beanName, null) {
                                        // 是不是以&开头的BeanName,主要是做一个校验,&不能随便乱用
                                        // 如果beanName存在&的情况下,当前获取到的实例实际上就是目标实例
                                        if (BeanFactoryUtils.isFactoryDereference(name)) {
                                            // 如果bean实例存在,但是beanName是以&开头,但是类型又不是FactoryBean,抛出异常
                                            if (!(beanInstance instanceof FactoryBean)) {
                                                throw new BeanIsNotAFactoryException(beanName, beanInstance.getClass());
                                            }
                                            // 如果代理的BD是FactoryBean实例,标记当前BD为factoryBean
                                            if (mbd != null) {
                                                mbd.isFactoryBean = true;
                                            }
                                            return beanInstance;
                                        }

                                        // 如果实例不是FactoryBean,直接返回
                                        if (!(beanInstance instanceof FactoryBean)) {
                                            return beanInstance;
                                        }
                                        // 这里处理的是BeanName不是以&开头,但又是一个FactoryBean
                                        // 我们的作用于代理的ScopedProxyFactoryBean就是这种情况
                                        Object object = null;
                                        // 如果是代理的BD
                                        if (mbd != null) {
                                            // 标记BD为FactoryBean
                                            mbd.isFactoryBean = true;
                                        } else {
                                            // 不是代理的BD,直接从FactoryBean创建的对象缓存中获取
                                            object = getCachedObjectForFactoryBean(beanName);
                                        }
                                        // 如果缓存中没有获取到
                                        if (object == null) {
                                            // 获取到BD
                                            FactoryBean<?> factory = (FactoryBean<?>) beanInstance;
                                            // 如果不是代理的BD,并且当前容器包含这个Bean
                                            if (mbd == null && containsBeanDefinition(beanName)) {
                                                // 获取原始Bean的BD
                                                mbd = getMergedLocalBeanDefinition(beanName);
                                            }
                                            boolean synthetic = (mbd != null && mbd.isSynthetic());
                                            // 从FactoryBean获取BD
                                            object = getObjectFromFactoryBean(factory, beanName, !synthetic) {
                                                // 这个时候,获取到的就是ScopedProxyFactoryBean中已经创建好的代理对象
                                                object = factory.getObject();
                                            }
                                        }
                                        return object;
                                    }
                                }
                                // 如果不存在,表示没有创建
                                else {
                                    // 原型Bean不支持循环依赖
                                    if (isPrototypeCurrentlyInCreation(beanName)) {
                                        throw new BeanCurrentlyInCreationException(beanName);
                                    }
                                }
                            },args));
                        }
                        return null
                    }
                    // 如果上面找到了能注入的Bean,直接获取实例注入
                    if (namedBean != null) {
                        return namedBean.getBeanInstance();
                    }
                }
            }
        }
    }

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值