Spring源码分析(BeanDefinition)

Spring源码分析(BeanDefinition)

一、概述

1、BeanDefinition 的理解

BeanDefinition 类似于 Java 中的 Class,Class 是创建对象的模板,而 BeanDefinition 就是创建生成 Bean的模板。

BeanDefinition 生成 Bean 实例,Bean实例交给 BeanFactory 管理,BeanFactory 交给 ApplicationContext 提供基础服务。

在这里插入图片描述

2、BeanDefinition 接口

BeanDefinition 中保存了 Bean 的信息(Bean 在代码层面上可以简单认为是 BeanDefinition 的实例)

public interface BeanDefinition extends AttributeAccessor, BeanMetadataElement {

    // Bean的作用域:默认只提供 sington 和 prototype 两种
    // web扩展的作用域:request, session, globalSession, application, websocket
    String SCOPE_SINGLETON = ConfigurableBeanFactory.SCOPE_SINGLETON;	// 单例
    String SCOPE_PROTOTYPE = ConfigurableBeanFactory.SCOPE_PROTOTYPE;	// 原型(多例)

    // 设置Bean的作用域
    void setScope(@Nullable String scope);   
    @Nullable
    String getScope();

    // 三个角色类型
    int ROLE_APPLICATION = 0;		// 表示这个 Bean 是用户自己定义的 Bean
    int ROLE_SUPPORT = 1;			// 表示这个 Bean 是某些复杂配置的支撑部分
    int ROLE_INFRASTRUCTURE = 2;	// 表示这个 Bean 是 Spring 内部的 Bean

    // 设置角色类型
    void setRole(int role);
    int getRole();

    
    // Modifiable attributes

    
	// 设置父 Bean(这里是 bean 继承,不是 java 继承)
    void setParentName(@Nullable String parentName); 
    @Nullable
    String getParentName();

    // 设置 Bean 的类名称(将来是要通过反射来生成实例的)
    void setBeanClassName(@Nullable String beanClassName);    
    @Nullable
    String getBeanClassName();

	// 设置是否懒加载	<bean lazy-init="">
    void setLazyInit(boolean lazyInit);
    boolean isLazyInit();

    // 依赖的bean列表 <bean depends-on=""> @DependsOn
    void setDependsOn(@Nullable String... dependsOn);
    @Nullable
    String[] getDependsOn();

    // 设置该 Bean 是否可以注入到其他 Bean 中
    // 只对根据类型注入有效,如果根据名称注入,即使这边设置了 false,也是可以的
    void setAutowireCandidate(boolean autowireCandidate);
    boolean isAutowireCandidate();

	// 同一接口的多个实现,如果不指定名字的话,Spring 会优先选择设置 primary 为 true 的 bean
    void setPrimary(boolean primary);
    boolean isPrimary();

    // 如果该 Bean 采用工厂方法生成,指定工厂名称。
    void setFactoryBeanName(@Nullable String factoryBeanName);
    @Nullable
    String getFactoryBeanName();

    // 指定工厂类中的 工厂方法名称
    void setFactoryMethodName(@Nullable String factoryMethodName);
    @Nullable
    String getFactoryMethodName();

    /**
	 * Bean 构造方法的参数,用于实例化 Bean 判断
	 */
    ConstructorArgumentValues getConstructorArgumentValues();
    default boolean hasConstructorArgumentValues() {
        return !getConstructorArgumentValues().isEmpty();
    }

    /**
	 * Bean 中的属性值
	 */
    MutablePropertyValues getPropertyValues();
    default boolean hasPropertyValues() {
        return !getPropertyValues().isEmpty();
    }

    /**
	 * Bean 初始化方法 @Bean(initMethod="init") 来指定初始化方法 类似 @PostConstruct
	 */
    void setInitMethodName(@Nullable String initMethodName);
    @Nullable
    String getInitMethodName();

    /**
	 * Bean 销毁方法  @Bean(destroyMethod = "") 类似 @PreDestory
	 */
    void setDestroyMethodName(@Nullable String destroyMethodName);
    @Nullable
    String getDestroyMethodName();

    /**
	 * Bean 描述信息
	 */
    void setDescription(@Nullable String description);
    @Nullable
    String getDescription();

    
    // Read-only attributes
    
    
    // 返回此bean定义的可解析类型
    ResolvableType getResolvableType();

    boolean isSingleton();
    boolean isPrototype();

    boolean isAbstract();

    @Nullable
    String getResourceDescription();

    @Nullable
    BeanDefinition getOriginatingBeanDefinition();

}

3、BeanDefinition 的实现

在这里插入图片描述

主要分为 以 AnnotatedBeanDefinition 为首的 注解派 和 以 AbstractBeanDefinition 为首的 常规派。

  • @Controller、@Service、@Mapper 什么的都包装成了 ScannedGenericBeanDefinition
  • @Configuration 以及 一些自动装配类 都包装成了 AnnotatedGenericBeanDefinition
  • @Configuration 里的 @Bean 都包装成了 ConfigurationClassBeanDefinition

4、BeanDefinitionHolder 类

public class BeanDefinitionHolder implements BeanMetadataElement {

    // bean的定义
    private final BeanDefinition beanDefinition;

    // bean的名称
    private final String beanName;

    // bean的别名
    private final String[] aliases;
    
    //...
}

二、BeanDefinition 的加载

通过 AbstractRefreshableApplicationContextloadBeanDefinitions 方法 加载 BeanDefinition

// org.springframework.context.support.AbstractRefreshableApplicationContext

protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
    throws BeansException, IOException;

这里我们主要看 AnnotationConfigWebApplicationContext 中的实现

// org.springframework.web.context.support.AnnotationConfigWebApplicationContext

protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) {    
    // reader 用于处理注解的bean定义
    AnnotatedBeanDefinitionReader reader = this.getAnnotatedBeanDefinitionReader(beanFactory);
    // scanner 用于扫描类路径下的bean定义
    ClassPathBeanDefinitionScanner scanner = this.getClassPathBeanDefinitionScanner(beanFactory);

    // 获取BeanName生成器
    BeanNameGenerator beanNameGenerator = getBeanNameGenerator();
    if (beanNameGenerator != null) {
        // 设置到reader和scanner
        reader.setBeanNameGenerator(beanNameGenerator);
        scanner.setBeanNameGenerator(beanNameGenerator);
        // 注册为单例bean(internalConfigurationBeanNameGenerator)
        beanFactory.registerSingleton(AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR, beanNameGenerator);
    }

    // 获取Scope解析器
    ScopeMetadataResolver scopeMetadataResolver = getScopeMetadataResolver();
    if (scopeMetadataResolver != null) {
        // 设置到reader和scanner
        reader.setScopeMetadataResolver(scopeMetadataResolver);
        scanner.setScopeMetadataResolver(scopeMetadataResolver);
    }

    // 注册组件bean
    if (!this.componentClasses.isEmpty()) {
        // ...
        reader.register(ClassUtils.toClassArray(this.componentClasses));
    }

    // 扫描并注册基础包路径下的bean
    if (!this.basePackages.isEmpty()) {
        // ...
        scanner.scan(StringUtils.toStringArray(this.basePackages));
    }

    // 获取存放了 BeanDefinition 的资源路径
    String[] configLocations = getConfigLocations();
    if (configLocations != null) {
        // 从配置位置加载 BeanDefinition
        for (String configLocation : configLocations) {
            try {
                // 使用 当前容器的类加载器 加载指定路径的字节码类文件
                Class<?> clazz = ClassUtils.forName(configLocation, getClassLoader());
                if (logger.isTraceEnabled()) {
                    logger.trace("Registering [" + configLocation + "]");
                }
                // 注册加载的clazz
                reader.register(clazz);
            } 
            catch (ClassNotFoundException ex) {
                // logger...
                
                // 如果类加载器加载失败,则改用scanner扫描给定路径包及其子包中的类
                int count = scanner.scan(configLocation);
                if (count == 0 && logger.isDebugEnabled()) {
                    // logger...
                }
            }
        }
    }
}

可以看到,BeanDefinition的注册主要由 readerscanner 完成:

  • 通过 AnnotatedBeanDefinitionReaderregister 方法,注册组件Bean。
  • 通过 ClassPathBeanDefinitionScannerscan 方法,扫描并注册指定路径下的Bean。

这两个都用于注册 BeanDefinition,两个类功能整体上类似。

1、reader 的获取

// org.springframework.web.context.support.AnnotationConfigWebApplicationContext

protected AnnotatedBeanDefinitionReader getAnnotatedBeanDefinitionReader(DefaultListableBeanFactory beanFactory) {
    return new AnnotatedBeanDefinitionReader(beanFactory, getEnvironment());
}
// org.springframework.context.annotation.AnnotatedBeanDefinitionReader

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    Assert.notNull(environment, "Environment must not be null");
    this.registry = registry;
    this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
    // 注册相关处理器
    AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}

从上面的代码可知,实例化AnnotatedBeanDefinitionReader时,会注册相关的处理器:

类名称说明
ConfigurationClassPostProcessor处理@Configuration注解
AutowiredAnnotationBeanPostProcessor处理@Autowired@Value注解
RequiredAnnotationBeanPostProcessor处理@Required注解
CommonAnnotationBeanPostProcessor处理@Resource注解
EventListenerMethodProcessor处理@EventListener注解
DefaultEventListenerFactory处理@EventListener注解

PS:scanner.scan 也有 registerAnnotationConfigProcessors 这块逻辑。

1)registerAnnotationConfigProcessors

下面看一下代码:

// org.springframework.context.annotation.AnnotationConfigUtils

public static void registerAnnotationConfigProcessors(BeanDefinitionRegistry registry) {
    registerAnnotationConfigProcessors(registry, null);
}

public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
    BeanDefinitionRegistry registry, @Nullable Object source) {

    // 获取beanFactory
    DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);

    if (beanFactory != null) {
        // 设置 AnnotationAwareOrderComparator 作为依赖比较器
        // 为了处理 @Order 注解
        if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
            beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
        }
        // 设置 ContextAnnotationAutowireCandidateResolver 作为自动装配候选解析器
        // 为了自动装配时能够正确地处理 @Autowired 和 @Qualifier 注解,以及其他相关的上下文注解。
        if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
            beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
        }
    }

    Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);

    // internalConfigurationAnnotationProcessor(内部管理 Configuration 注解处理器 的 bean 的名称)
    if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        // ConfigurationClassPostProcessor(处理 @Configuration 类)
        RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // internalAutowiredAnnotationProcessor(内部管理 Autowired 注解处理器 的 bean 的名称)
    if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        // AutowiredAnnotationBeanPostProcessor(处理 @Autowired、@Value等)
        RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // internalCommonAnnotationProcessor(内部管理 JSR-250 注解处理器 的 bean 的名称)
    if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        // CommonAnnotationBeanPostProcessor(处理 @Resource、@PostConstruct、@PreDestroy等)
        RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // internalPersistenceAnnotationProcessor(内部管理  JPA 注解处理器 的 bean 的名称)
    if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
        RootBeanDefinition def = new RootBeanDefinition();
        try {
            // PersistenceAnnotationBeanPostProcessor(处理SpringJPA相关)
            def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
                                                AnnotationConfigUtils.class.getClassLoader()));
        }
        catch (ClassNotFoundException ex) {...}
        def.setSource(source);
        // internalPersistenceAnnotationProcessor
        beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
    }

    // internalEventListenerProcessor(内部管理 @EventListener 注解 处理器 的 bean 的名称)
    if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
        // EventListenerMethodProcessor(处理 @EventListener)
        RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
    }

    // internalEventListenerFactory(内部管理 EventListenerFactory 的 bean 的名称)
    if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
        // DefaultEventListenerFactory(处理 @EventListener)
        RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
        def.setSource(source);
        beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
    }

    return beanDefs;
}

2)registerPostProcessor

// org.springframework.context.annotation.AnnotationConfigUtils

private static BeanDefinitionHolder registerPostProcessor(
    BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {

    // 表明这个 Bean 是 Spring 内部的 Bean
    definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);

    // 注册相关处理器的BeanDefinition
    registry.registerBeanDefinition(beanName, definition);

    // 返回 BeanDefinitionHolder
    return new BeanDefinitionHolder(definition, beanName);
}

2、reader.register

// org.springframework.context.annotation.AnnotatedBeanDefinitionReader

public void register(Class<?>... componentClasses) {
    // 遍历注册每一个组件bean
    for (Class<?> componentClass : componentClasses) {
        registerBean(componentClass);
    }
}

public void registerBean(Class<?> beanClass) {
    // 注册单个组件bean
    doRegisterBean(beanClass, null, null, null, null);
}

private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
                                @Nullable Class<? extends Annotation>[] qualifiers, 
                                @Nullable Supplier<T> supplier,
                                @Nullable BeanDefinitionCustomizer[] customizers) {

    // 根据beanClass,构建AnnotatedGenericBeanDefinition(AnnotationMetadata + MethodMetadata)
    AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
    if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
        return;
    }

    abd.setInstanceSupplier(supplier);

    // 解析 @Scope
    ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
    abd.setScope(scopeMetadata.getScopeName());

    // 获取 beanName(指定了用指定的,否则用默认的)
    String beanName = (name != null ? name : 
                       this.beanNameGenerator.generateBeanName(abd, this.registry));

    // 处理 一些通用注解(@Lazy、@Primary、@DependsOn、@Role、@Description)
    AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

    // 处理 qualifiers
    if (qualifiers != null) {
        for (Class<? extends Annotation> qualifier : qualifiers) {
            // 如果配置了@Primary注解,设置该Bean为autowiring自动依赖注入装配时的首选
            if (Primary.class == qualifier) {
                abd.setPrimary(true);
            }
            // 如果配置了@Lazy注解,则设置该Bean为非延迟初始化
            else if (Lazy.class == qualifier) {
                abd.setLazyInit(true);
            }
            // 如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一个autowiring自动依赖注入装配限定符
            // 该Bean在进autowiring自动依赖注入装配时,根据名称装配限定符指定的Bean
            else {
                abd.addQualifier(new AutowireCandidateQualifier(qualifier));
            }
        }
    }

    // 应用 BeanDefinitionCustomizer 的 customize 方法
    if (customizers != null) {
        for (BeanDefinitionCustomizer customizer : customizers) {
            customizer.customize(abd);
        }
    }

    // 构建 BeanDefinitionHolder
    BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
 
    // 处理 @Scope 的 proxyMode 属性(如果需要代理,这里返回的是代理bd,但beanName不变)
    definitionHolder = AnnotationConfigUtils.
        applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

    // 注册 BeanDefinition
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}

3、scanner 的获取

// org.springframework.web.context.support.AnnotationConfigWebApplicationContext

protected ClassPathBeanDefinitionScanner getClassPathBeanDefinitionScanner(DefaultListableBeanFactory beanFactory) {
    return new ClassPathBeanDefinitionScanner(beanFactory, true, getEnvironment());
}
// org.springframework.context.annotation.ClassPathBeanDefinitionScanner

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
                                      Environment environment) {
    // 参数的 registry 就是 beanFactory,useDefaultFilters 就是 true
    this(registry, useDefaultFilters, environment,
         (registry instanceof ResourceLoader ? (ResourceLoader) registry : null));
}

public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
                                      Environment environment, @Nullable ResourceLoader resourceLoader) {
    Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
    this.registry = registry;

    if (useDefaultFilters) {
        // 注册默认的过滤器
        registerDefaultFilters();
    }

    setEnvironment(environment);
    setResourceLoader(resourceLoader);
}
// org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider

protected void registerDefaultFilters() {
    // Component.class
    this.includeFilters.add(new AnnotationTypeFilter(Component.class));
    ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();

    // javax.annotation.ManagedBean
    try {
        this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.annotation.ManagedBean", cl)), false));
        logger.trace("JSR-250 'javax.annotation.ManagedBean' found and supported for component scanning");
    }
    catch (ClassNotFoundException ex) {
        // JSR-250 1.1 API (as included in Java EE 6) not available - simply skip.
    }

    // javax.inject.Named
    try {
        this.includeFilters.add(new AnnotationTypeFilter(
            ((Class<? extends Annotation>) ClassUtils.forName("javax.inject.Named", cl)), false));
        logger.trace("JSR-330 'javax.inject.Named' annotation found and supported for component scanning");
    }
    catch (ClassNotFoundException ex) {
        // JSR-330 API not available - simply skip.
    }
}

4、scanner.scan

// org.springframework.context.annotation.ClassPathBeanDefinitionScanner

public int scan(String... basePackages) {
    // 获取容器中已经注册的Bean个数
    int beanCountAtScanStart = this.registry.getBeanDefinitionCount();

    // 扫描指定包的bean
    doScan(basePackages);

    // Register annotation config processors, if necessary.
    if (this.includeAnnotationConfig) {
        AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
    }

    // 返回扫描注册的Bean个数
    return (this.registry.getBeanDefinitionCount() - beanCountAtScanStart);
}

protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
    Assert.notEmpty(basePackages, "At least one base package must be specified");

    // 创建一个集合,存放扫描的BeanDefinition的封装
    Set<BeanDefinitionHolder> beanDefinitions = new LinkedHashSet<>();

    // 遍历要扫描的包
    for (String basePackage : basePackages) {
        // ------------------------------------------
        // 这里会真正执行资源扫描,并封装为BeanDefinition
        // ------------------------------------------
        Set<BeanDefinition> candidates = findCandidateComponents(basePackage);
        for (BeanDefinition candidate : candidates) {
            // 解析 @Scope
            ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
            candidate.setScope(scopeMetadata.getScopeName());
            // 获取 beanName
            String beanName = this.beanNameGenerator.generateBeanName(candidate, this.registry);
            // AbstractBeanDefinition 类型
            if (candidate instanceof AbstractBeanDefinition) {
                // 给 beanDefinition 设置 一些默认值 和 autowireCandidate
                postProcessBeanDefinition((AbstractBeanDefinition) candidate, beanName);
            }
            // AnnotatedBeanDefinition 类型
            if (candidate instanceof AnnotatedBeanDefinition) {
                // 处理一些通用注解(@Lazy、@Primary、@DependsOn、@Role、@Description)
                AnnotationConfigUtils.processCommonDefinitionAnnotations(
                    (AnnotatedBeanDefinition) candidate);
            }
            if (checkCandidate(beanName, candidate)) {
                // 构建 BeanDefinitionHolder
                BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(candidate, beanName);
                // 处理 @Scope 的 proxyMode 属性(如果需要代理,这里返回的是代理bd,但beanName不变)
                definitionHolder = AnnotationConfigUtils.
                    applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
                beanDefinitions.add(definitionHolder);
                // 注册bean
                registerBeanDefinition(definitionHolder, this.registry);
            }
        }
    }

    return beanDefinitions;
}

protected void registerBeanDefinition(BeanDefinitionHolder definitionHolder, 
                                      BeanDefinitionRegistry registry) {
    // 和reader一样,最终调用 BeanDefinitionReaderUtils 的 registerBeanDefinition 方法进行注册
    BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, registry);
}

5、@Scope 的 proxyMode

无论是 reader.register 还是 scanner.scan,都能看到这样一段代码

// 处理 @Scope 的 proxyMode 属性
definitionHolder = AnnotationConfigUtils.
    applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

这块代码主要处理了 @Scope 注解的 proxyMode 属性。

1)@Scope

首先我们看一下 @Scope 的属性

@Target({ElementType.TYPE, ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Documented
public @interface Scope {
    @AliasFor("scopeName")
	String value() default "";

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

    // 代理模式,默认不创建代理
    ScopedProxyMode proxyMode() default ScopedProxyMode.DEFAULT;
}
public enum ScopedProxyMode {
    DEFAULT,		// 一般等同于NO,除非在组件扫描指令级别配置了不同的默认值
    NO,				// 不创建代理对象
    INTERFACES,		// 使用jdk动态代理来创建代理对象
    TARGET_CLASS	// 使用cglib动态代理来创建代理对象
}

2)@Scope 的解析

public class AnnotatedBeanDefinitionReader {
    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();
    
    private <T> void doRegisterBean(...) {
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
    }
}
public class ClassPathBeanDefinitionScanner extends ClassPathScanningCandidateComponentProvider {
    private ScopeMetadataResolver scopeMetadataResolver = new AnnotationScopeMetadataResolver();

    protected Set<BeanDefinitionHolder> doScan(String... basePackages) {
        ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(candidate);
    }
}

可以看到,无论是 reader 还是 scanner,最终都是通过 AnnotationScopeMetadataResolver 解析 @Scope 的

// org.springframework.context.annotation.AnnotationScopeMetadataResolver

private final ScopedProxyMode defaultProxyMode;

public AnnotationScopeMetadataResolver() {
    this.defaultProxyMode = ScopedProxyMode.NO;
}

@Override
public ScopeMetadata resolveScopeMetadata(BeanDefinition definition) {
    ScopeMetadata metadata = new ScopeMetadata();
    if (definition instanceof AnnotatedBeanDefinition) {
        AnnotatedBeanDefinition annDef = (AnnotatedBeanDefinition) definition;
        AnnotationAttributes attributes = AnnotationConfigUtils.attributesFor(
            annDef.getMetadata(), this.scopeAnnotationType);
        if (attributes != null) {
            metadata.setScopeName(attributes.getString("value"));
            ScopedProxyMode proxyMode = attributes.getEnum("proxyMode");
            // ScopedProxyMode.DEFAULT 使用 ScopedProxyMode.NO 的 proxyMode 值
            if (proxyMode == ScopedProxyMode.DEFAULT) {
                proxyMode = this.defaultProxyMode;
            }
            metadata.setScopedProxyMode(proxyMode);
        }
    }
    return metadata;
}

3)applyScopedProxyMode

然后,我们再看一下 AnnotationConfigUtils 的 applyScopedProxyMode 方法是怎么处理 @Scope 的 proxyMode 属性的

// org.springframework.context.annotation.AnnotationConfigUtils

static BeanDefinitionHolder applyScopedProxyMode(
    ScopeMetadata metadata, BeanDefinitionHolder definition, BeanDefinitionRegistry registry) {

    // 获取 @Scope 的 proxyMode 属性
    ScopedProxyMode scopedProxyMode = metadata.getScopedProxyMode();

    // proxyMode 的值为 NO 或 DEFAULT
    if (scopedProxyMode.equals(ScopedProxyMode.NO)) {
        // 直接返回
        return definition;
    }

    // proxyMode 的值为 INTERFACES 或 TARGET_CLASS

    // 是否为cglib动态代理(INTERFACES 表示使用jdk动态代理;TARGET_CLASS 表示使用cglib动态代理)
    boolean proxyTargetClass = scopedProxyMode.equals(ScopedProxyMode.TARGET_CLASS);

    // 创建Scope代理
    return ScopedProxyCreator.createScopedProxy(definition, registry, proxyTargetClass);
}
// org.springframework.context.annotation.ScopedProxyCreator

public static BeanDefinitionHolder createScopedProxy(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry, boolean proxyTargetClass) {
    
    return ScopedProxyUtils.createScopedProxy(definitionHolder, registry, proxyTargetClass);
}
// org.springframework.aop.scope.ScopedProxyUtils

public static BeanDefinitionHolder createScopedProxy(BeanDefinitionHolder definition,
                                                     BeanDefinitionRegistry registry, 
                                                     boolean proxyTargetClass) {
    String originalBeanName = definition.getBeanName();
    BeanDefinition targetDefinition = definition.getBeanDefinition();

    // targetBeanName = "scopedTarget." + originalBeanName
    String targetBeanName = getTargetBeanName(originalBeanName);

    // 创建代理的 BeanDefinition
    RootBeanDefinition proxyDefinition = new RootBeanDefinition(ScopedProxyFactoryBean.class);
    proxyDefinition.setDecoratedDefinition(new BeanDefinitionHolder(targetDefinition, targetBeanName));
    proxyDefinition.setOriginatingBeanDefinition(targetDefinition);
    proxyDefinition.setSource(definition.getSource());
    proxyDefinition.setRole(targetDefinition.getRole());
    proxyDefinition.getPropertyValues().add("targetBeanName", targetBeanName);

    // 是否为cglib动态代理
    if (proxyTargetClass) {
        // cglib动态代理
        targetDefinition.setAttribute(AutoProxyUtils.PRESERVE_TARGET_CLASS_ATTRIBUTE, Boolean.TRUE);
        // ScopedProxyFactoryBean 的 proxyTargetClass 默认为TRUE,因此这里不需要显式设置
    } else {
        // jdk动态代理
        proxyDefinition.getPropertyValues().add("proxyTargetClass", Boolean.FALSE);
    }

    // Copy autowire settings from original bean definition.
    proxyDefinition.setAutowireCandidate(targetDefinition.isAutowireCandidate());
    proxyDefinition.setPrimary(targetDefinition.isPrimary());
    if (targetDefinition instanceof AbstractBeanDefinition) {
        proxyDefinition.copyQualifiersFrom((AbstractBeanDefinition) targetDefinition);
    }

    // 原来的 BeanDefinition 不作为注入的候选者
    targetDefinition.setAutowireCandidate(false);
    targetDefinition.setPrimary(false);

    // 单独注册目标bean(beanName = "scopedTarget." + originalBeanName)
    registry.registerBeanDefinition(targetBeanName, targetDefinition);

    // 这里beanName还是用的原始的,但是beanDefinition已经替换成代理的了
    return new BeanDefinitionHolder(proxyDefinition, originalBeanName, definition.getAliases());
}

4)ScopedProxyFactoryBean

applyScopedProxyMode 返回的 BeanDefinitionHolder 的 BeanDefinition 的 beanClass 被改成了 ScopedProxyFactoryBean

public class ScopedProxyFactoryBean extends ProxyConfig
    implements FactoryBean<Object>, BeanFactoryAware, AopInfrastructureBean {...}

ScopedProxyFactoryBean 实现了 FactoryBean,重写了以下方法

// org.springframework.aop.scope.ScopedProxyFactoryBean

@Nullable
private Object proxy;

@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();
    }
    return this.scopedTargetSource.getTargetClass();
}

@Override
public boolean isSingleton() {
    return true;
}

ScopedProxyFactoryBean 还实现了 BeanFactoryAware,重写了 setBeanFactory 方法(proxy 就是在这里生成的)

// org.springframework.aop.scope.ScopedProxyFactoryBean

private final SimpleBeanTargetSource scopedTargetSource = new SimpleBeanTargetSource();

@Override
public void setBeanFactory(BeanFactory beanFactory) {
    if (!(beanFactory instanceof ConfigurableBeanFactory)) {
        throw new IllegalStateException("Not running in a ConfigurableBeanFactory: " + beanFactory);
    }
    ConfigurableBeanFactory cbf = (ConfigurableBeanFactory) beanFactory;

    this.scopedTargetSource.setBeanFactory(beanFactory);

    ProxyFactory pf = new ProxyFactory();
    pf.copyFrom(this);
    pf.setTargetSource(this.scopedTargetSource);

    // ...

    // 创建代理对象
    this.proxy = pf.getProxy(cbf.getBeanClassLoader());
}

Cglib 代理 会进入到 CglibAopProxy 的内部类 DynamicAdvisedInterceptor 的 intercept 方法

// org.springframework.aop.framework.CglibAopProxy.DynamicAdvisedInterceptor

@Override
@Nullable
public Object intercept(Object proxy, Method method, Object[] args, MethodProxy methodProxy) throws Throwable {
    // ...

    // getTargetSource() 获取到的就是上面的 scopedTargetSource 对象(new SimpleBeanTargetSource)
    TargetSource targetSource = this.advised.getTargetSource();
    try {
        // ...

        // 这里调用的是 SimpleBeanTargetSource 的 getTarget()
        target = targetSource.getTarget();

        // ...
    } 
    // ...
}
public class SimpleBeanTargetSource extends AbstractBeanFactoryBasedTargetSource {
    @Override
    public Object getTarget() throws Exception {
        // 触发 getBean(),如果是 prototype,每次都会返回一个新的 bean
        return getBeanFactory().getBean(getTargetBeanName());
    }
}

5)小结

  • @Scope 的 proxyMode 为 DEFAULT 和 NO —> 只会有一个 BeanDefinition,就是原始的 Bean
  • @Scope 的 proxyMode 为 INTERFACES 或 TARGET_CLASS —> 会有两个 BeanDefinition
    • 原始的 BeanDefinition:beanName = “scopedTarget.” + originalBeanName(不会作为注入的候选者)
    • 代理的 BeanDefinition:beanName = originalBeanName(beanClass = ScopedProxyFactoryBean.class)

BeanDefinition 中的 beanClass 被偷梁换柱成了 ScopedProxyFactoryBean,获取bean通过 getObject 返回 proxy

三、BeanDefinition 的注册

无论是 reader 还是 scanner,最终都会调用 BeanDefinitionReaderUtils 的 registerBeanDefinition 方法进行注册

// org.springframework.beans.factory.support.BeanDefinitionReaderUtils

public static void registerBeanDefinition(
    BeanDefinitionHolder definitionHolder, BeanDefinitionRegistry registry)
    throws BeanDefinitionStoreException {

    // 注册 BeanDefinition
    // 将 <beanName, beanDefinition> 存入 DefaultListableBeanFactory 的 beanDefinitionMap 中
    String beanName = definitionHolder.getBeanName();
    registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

    // 注册 aliases 别名
    // 将 <alias, beanName> 存入 aliasesMap 中,获取bean时,先根据alias找到beanName,然后再获取bean
    String[] aliases = definitionHolder.getAliases();
    if (aliases != null) {
        for (String alias : aliases) {
            registry.registerAlias(beanName, alias);
        }
    }
}

1、registerBeanDefinition

BeanDefinitionReaderUtils 通过 BeanDefinitionRegistry 的 registerBeanDefinition 方法 注册 BeanDefinition

// BeanDefinitionRegistry 继承了 AliasRegistry
public interface BeanDefinitionRegistry extends AliasRegistry {
    void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
        throws BeanDefinitionStoreException;
}

而 DefaultListableBeanFactory 实现了 BeanDefinitionRegistry 接口,重写了 registerBeanDefinition 方法

public class DefaultListableBeanFactory extends AbstractAutowireCapableBeanFactory
    // DefaultListableBeanFactory 实现了 BeanDefinitionRegistry
    implements ConfigurableListableBeanFactory, BeanDefinitionRegistry, Serializable {...}

因此,reader.register 和 scanner.scan 最终都会走到 DefaultListableBeanFactory 重写的 registerBeanDefinition 方法

// org.springframework.beans.factory.support.DefaultListableBeanFactory
@Override
public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition)
    throws BeanDefinitionStoreException {

    // 一些校验...

    // 判断 BeanDefinition 是否已存在
    BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);

    // 当前 BeanDefinition 已存在
    if (existingDefinition != null) {
        // 是否允许bean覆盖
        if (!isAllowBeanDefinitionOverriding()) {
            throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition);
        } 
        // ...
        // bean覆盖
        this.beanDefinitionMap.put(beanName, beanDefinition);
    }

    // 当前 BeanDefinition 不存在
    else {
        // 检查这个工厂的bean创建阶段是否已经开始,即是否有任何bean在此期间被标记为已创建。
        
        // 已经开始创建Bean了
        if (hasBeanCreationStarted()) {
            // 这种情况需要加锁
            synchronized (this.beanDefinitionMap) {
                this.beanDefinitionMap.put(beanName, beanDefinition);
                List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
                updatedDefinitions.addAll(this.beanDefinitionNames);
                updatedDefinitions.add(beanName);
                this.beanDefinitionNames = updatedDefinitions;
                removeManualSingletonName(beanName);
            }
        }

        // 还没有开始创建Bean
        else {
            // 将 BeanDefinition 存入 DefaultListableBeanFactory 的 beanDefinitionMap 中
            // beanDefinitionMap 这个 map 保存了所有的 BeanDefinition
            this.beanDefinitionMap.put(beanName, beanDefinition);
            // 这是个 ArrayList,所以会按照 bean 配置的顺序保存每一个注册的 Bean 的名字
            this.beanDefinitionNames.add(beanName);
            // 从手动注册的集合里删除,走到这里的 Bean 不是手动注册的
            // 手动指的是调用 registerSingleton(String beanName, Object singletonObject) 注册
            removeManualSingletonName(beanName);
        }
        this.frozenBeanDefinitionNames = null;
    }

    if (existingDefinition != null || containsSingleton(beanName)) {
        // 重置所有已经注册过的 BeanDefinition 的缓存
        resetBeanDefinition(beanName);
    }

    else if (isConfigurationFrozen()) {
        clearByTypeCache();
    }
}

2、registerAlias

  • register.registerAlias 最终调用的是 SimpleAliasRegistry 中的 registerAlias 方法
  • DefaultListableBeanFactory 也是 SimpleAliasRegistry 的子类

在这里插入图片描述

public class SimpleAliasRegistry implements AliasRegistry {
    
    protected final Log logger = LogFactory.getLog(this.getClass());

    // 保存别名信息的map:<alias, beanName>
    // 获取bean的时候,先根据 alias 获取 beanName,然后再查找bean
    private final Map<String, String> aliasMap = new ConcurrentHashMap(16);

    public SimpleAliasRegistry() {}

    public void registerAlias(String name, String alias) {
        Assert.hasText(name, "'name' must not be empty");
        Assert.hasText(alias, "'alias' must not be empty");
        
        synchronized(this.aliasMap) {
            if (alias.equals(name)) {
                // alias 和 beanName 一致
                this.aliasMap.remove(alias);
                
                // logger...
            } else {
                String registeredName = (String) this.aliasMap.get(alias);
                if (registeredName != null) {
                    // alias已存在
                    if (registeredName.equals(name)) {
                        return;
                    }

                    // alias对应的beanName不一致
                    
                    // 不允许
                    if (!this.allowAliasOverriding()) {
                        throw new IllegalStateException(...);
                    }

                    // logger...
                }

                this.checkForAliasCircle(name, alias);
                
                // 保存 <alias, beanName>
                this.aliasMap.put(alias, name);
                
                // logger...
            }

        }
    }
}
  • 16
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

scj1022

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值