接着上一篇. 这里来看一下 register(componentClasses)
register
@Override public void register(Class>... componentClasses) { Assert.notEmpty(componentClasses, "At least one component class must be specified"); this.reader.register(componentClasses); }
从代码来看, 注册的工作, 是 AnnotatedBeanDefinitionReader 来完成的. 由于 componentClasses 是一个可变数组, 所以, 还是需要对他进行循环注册的.
循环里面, 最终会调用 org.springframework.context.annotation.AnnotatedBeanDefinitionReader#doRegisterBean 方法.
进方法时, beanClass 是 StartConfig, 其他参数都是 null.
/** * Register a bean from the given bean class, deriving its metadata from * class-declared annotations. * @param beanClass the class of the bean * @param instanceSupplier a callback for creating an instance of the bean * (may be {@code null}) * @param name an explicit name for the bean * @param qualifiers specific qualifier annotations to consider, if any, * in addition to qualifiers at the bean class level * @param definitionCustomizers one or more callbacks for customizing the * factory's {@link BeanDefinition}, e.g. setting a lazy-init or primary flag * @since 5.0 */void doRegisterBean(Class beanClass, @Nullable Supplier instanceSupplier, @Nullable String name, @Nullable Class extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) { /** * 根据指定的bean创建一个AnnotatedGenericBeanDefinition, 从字面意思可以理解为 一般注解bd * AnnotatedGenericBeanDefinition包含了类的其他信息,比如一些元信息, scope, lazy等等 */ AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass); /** * 判断这个类是否需要跳过解析 * 通过代码可以知道spring判断是否跳过解析,主要判断类有没有加注解 */ if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) { return; } abd.setInstanceSupplier(instanceSupplier); //得到类的作用域 ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd); //把类的作用域添加到数据结构结构中 abd.setScope(scopeMetadata.getScopeName()); //生成类的名字 通过beanNameGenerator String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry)); /** * 处理类当中的通用注解 * 主要解析 Lazy DependsOn Primary Role * 处理完成之后processCommonDefinitionAnnotations中依然是把他添加到 abd 中 */ AnnotationConfigUtils.processCommonDefinitionAnnotations(abd); /** * 如果在向容器注册注解Bean定义时,使用了额外的限定符注解则解析 * 关于Qualifier和Primary前面的课当中讲过,主要涉及到spring的自动装配 * 这里需要注意的 * byName和qualifiers这个变量是Annotation类型的数组,里面存不仅仅是Qualifier注解 * 理论上里面里面存的是一切注解,所以可以看到下面的代码spring去循环了这个数组 * 然后依次判断了注解当中是否包含了Primary,是否包含了Lazy */ if (qualifiers != null) { for (Class extends Annotation> qualifier : qualifiers) { //如果配置了@Primary注解,则作为首选 if (Primary.class == qualifier) { abd.setPrimary(true); } //懒加载 else if (Lazy.class == qualifier) { abd.setLazyInit(true); } else { //如果使用了除@Primary和@Lazy以外的其他注解,则为该Bean添加一个根据名字自动装配的限定符 abd.addQualifier(new AutowireCandidateQualifier(qualifier)); } } } //自定义注解 for (BeanDefinitionCustomizer customizer : definitionCustomizers) { customizer.customize(abd); } //这里 BeanDefinitionHolder 对 BeanDefinition 和 beanName 进行了封装 //对 applyScopedProxyMode 有作用, 对 registerBeanDefinition 没啥作用 BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName); /** * ScopedProxyMode 这个知识点比较复杂,需要结合 web去理解 */ definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry); /** * 把上述的这个数据结构注册给registry * registy就是AnnotatonConfigApplicationContext * AnnotatonConfigApplicationContext在初始化的時候通過調用父類的构造方法 * 实例化了一个DefaultListableBeanFactory * registerBeanDefinition里面就是把definitionHolder这个数据结构包含的信息注册到 * DefaultListableBeanFactory这个工厂 */ BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry); }
这里主要就是解析 配置类, 设置一些默认配置. 将最后的结果封装到 abd (AnnotatedGenericBeanDefinition) 中, 然后通过 registerBeanDefinition 方法, 注册到容器中.
registerBeanDefinition方法不但会注册 bean 的名字, 还会对别名进行注册. 别名可以不用管. 主要是调用了
org.springframework.beans.factory.support.DefaultListableBeanFactory#registerBeanDefinition 方法, 内容如下:
/** * 通过 this.beanDefinitionMap.put(beanName, beanDefinition) 进行 bean 的注册 */ @Override public void registerBeanDefinition(String beanName, BeanDefinition beanDefinition) throws BeanDefinitionStoreException { Assert.hasText(beanName, "Bean name must not be empty"); Assert.notNull(beanDefinition, "BeanDefinition must not be null"); if (beanDefinition instanceof AbstractBeanDefinition) { try { ((AbstractBeanDefinition) beanDefinition).validate(); } catch (BeanDefinitionValidationException ex) { throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName, "Validation of bean definition failed", ex); } } BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName); if (existingDefinition != null) { if (!isAllowBeanDefinitionOverriding()) { throw new BeanDefinitionOverrideException(beanName, beanDefinition, existingDefinition); } else if (existingDefinition.getRole() < beanDefinition.getRole()) { // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE if (logger.isInfoEnabled()) { logger.info("Overriding user-defined bean definition for bean '" + beanName + "' with a framework-generated bean definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else if (!beanDefinition.equals(existingDefinition)) { if (logger.isDebugEnabled()) { logger.debug("Overriding bean definition for bean '" + beanName + "' with a different definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } else { if (logger.isTraceEnabled()) { logger.trace("Overriding bean definition for bean '" + beanName + "' with an equivalent definition: replacing [" + existingDefinition + "] with [" + beanDefinition + "]"); } } this.beanDefinitionMap.put(beanName, beanDefinition); } else { if (hasBeanCreationStarted()) { // Cannot modify startup-time collection elements anymore (for stable iteration) synchronized (this.beanDefinitionMap) { this.beanDefinitionMap.put(beanName, beanDefinition); ListupdatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1); updatedDefinitions.addAll(this.beanDefinitionNames); updatedDefinitions.add(beanName); this.beanDefinitionNames = updatedDefinitions; removeManualSingletonName(beanName); } } else { // Still in startup registration phase this.beanDefinitionMap.put(beanName, beanDefinition); this.beanDefinitionNames.add(beanName); removeManualSingletonName(beanName); } this.frozenBeanDefinitionNames = null; } if (existingDefinition != null || containsSingleton(beanName)) { resetBeanDefinition(beanName); } }
从源码上看, register 方法, 主要就是解析 配置类, 将配置类转换成 BeanDefinition, 设置一些默认属性, 然后注册到 spring (BeanFactory) 容器中.
特别需要注意的是, 此时配置类, 并没有被创建出来, 只是解析了一番, 相当于是给 spring 写了一份说明. 后面 spring 会根据这份说明, 来创建和解析配置类.