AnnotatedBeanDefinitionReader:读取注解的Bean定义读取器,并将其设置到容器中 属性: BeanDefinitionRegistry registry 注册器 BeanNameGenerator beanNameGenerator 注解的名称生成器 ScopeMetadataResolver scopeMetadataResolver 通过resolveScopeMetadata方法解析注解Bean定义类的作用域元信息,即判断注册的Bean是原生类型还是单例类型 ConditionEvaluator conditionEvaluator 条件注解解析执行器
1、 doRegisterBean Bean定义读取器想容器注册注解Bean定义类 创建AnnotatedGenericBeanDefinition 类注解初始化的一些定义 解析注解Bean的作用域,生成注解Bean名称,处理通用注解,处理额外限定符注解Primary,Lazy,如果使用则为该Bean添加一个autowiring自动依赖注入装配限定符1 创建BeanDefinitionHolder 封装注解Bean定义类数据,如果是代理类创建代理对象 通过 BeanDefinitionReaderUtils.registerBeanDefinition 向IOC容器中注册注解Bean定义对象
ClassPathBeanDefinitionScanner:一个扫描指定类路径中注解Bean定义的扫描器,并将其设置到容器中 resourcePatternResolver 资源加载器,根据匹配规则获取Resource[] meteDataFactory 根据Resource获取MetadataReader对象,提供了获取一个Class文件的ClassMetadata和AnnotationMetadata的操作 根据过滤器匹配规则匹配MetadataReader中的类进行过滤,转换MetadataReader为BeanDefintion 1、使用ComponentScan根据指定包名扫描包名下带@service注解相关的类,然后转换解析为BeanDefinition。 2、ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) 创建一个类路径Bean定义扫描器 3、int scan(String... basePackages) 调用类路径Bean定义扫描器入口方法,返回注册的Bean个数 先通过Set<BeanDefinitionHolder> doScan(String... basePackages) 扫描给定bao及其子包, 再通过AnnotationConfigUtils.registerAnnotationConfigProcessors 进行注册 4、Set<BeanDefinitionHolder> doScan(String... basePackages) 步骤 1、遍历 basePackages 2、根据basePackage类路径获取符合条件的Bean定义 1、判断是否是Spring默认的注解,即Spring默认的@Component、@Repository、@Service、 //@Controller注解的Bean,以及JavaEE6的@ManagedBean和JSR-330的@Named注解 2、是addCandidateComponentsFromIndex 返回扫描到的类集合定义信息 1、循环includeFilters 获取TypeFilter 过滤出 AnnotationTypeFilter 通过注解的过滤规则,后面classes 参数写要过滤的注解的类 AssignableTypeFilter 通过指定类型过滤规则,后面的classes参数写指定的类 2、为指定资源获取元数据读取器,元信息读取器通过汇编ASM 读取资源元信息MetadataReader metadataReader 3、通过构造的AnnotatedGenericBeanDefinition isCandidateComponent方法判断将符合条件的BeanDefinition集合返回。 5、循环BeanDefinition集合,通过scopeMetadataResolver获取Bean作用域,通过beanNameGenerator生成bean名称,处理Bean的自动依赖注入装配属性,是Spring的注解bean,处理其通用的Spring注解,@Primary @Lazy @DependOn @Role @Description, 根据Bean名称检查Bean是否需要在容器中注册,或者在容器中冲突,根据注解中的作用域设置代理模式,向容器中注册烧苗到的Bean
AnnotationConfigApplicationContext 多态构造方法 1、默认构造方法初始化一个空容器,不包含任何Bean信息,需要在稍后通过调用其()方法配置类,并调用()方法刷新容器,触发容器对注解bean的载入、解析、注册过程。 2、AnnotationConfigApplicationContext(Class<?>... annotatedClasses)通过将涉及到的配置类传递给构造函数,以实现将相应配置类中的bean自动注册到容器中