Spring-AnnotationConfigApplicationContext

1. 简介

使用 AnnotationConfigApplicationContext 创建 Spring 应用上下文时,需要指定一个或多个配置类。,开发者可以直接在 Java 类中使用注解如 @Configuration、@Bean 等来声明和配置 Bean。

AnnotationConfigApplicationContext 属于 Spring 的 Java 配置支持模块,用于以纯 Java 注解的方式来替代 XML 配置文件来创建和管理 Spring 容器上下文。

ApplicationContext的三种加载应用上下文的方式:

  • AnnotationConfigApplicationContext

  • ClassPathXmlApplicationContext

  • FileSystemXmlApplicationContext

2. 构造方法

AnnotationConfigApplicationContext 共提供四个构造方法:

  • public AnnotationConfigApplicationContext()

    无参构造
    //就是初始化两个全局变量
    public AnnotationConfigApplicationContext() {
    	this.reader = new AnnotatedBeanDefinitionReader(this);
    	this.scanner = new ClassPathBeanDefinitionScanner(this);
    }
    
    	private static void test1(){
    		AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext();
    		context.register(TestBean.class, DogBean.class);
    		context.refresh();
    
    		TestBean bean = context.getBean(TestBean.class);
    		bean.helloSpring();
    	}
    

    无参构造,需要手动调用 register() 或者 scan() 和 refresh() 方法

  • public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory)

    以 beanFactory 为参数
        public AnnotationConfigApplicationContext(DefaultListableBeanFactory beanFactory) {
    		super(beanFactory);
    		this.reader = new AnnotatedBeanDefinitionReader(this);
    		this.scanner = new ClassPathBeanDefinitionScanner(this);
    	}
    
    private static void test2(){
      	AnnotationConfigApplicationContext context = new AnnotationConfigApplicationContext(new DefaultListableBeanFactory());
      	context.register(TestBean.class, DogBean.class);
      	context.refresh();
    
      	TestBean bean = context.getBean(TestBean.class);
      	bean.helloSpring();
    }
    

    相比无参构造,多了一个 super(beanFactory),看看 super(beanFactory) 做了什么事情:

    GenericApplicationContext.super()
    public GenericApplicationContext() {
      	this.beanFactory = new DefaultListableBeanFactory();
      }
    
      /**
       * Create a new GenericApplicationContext with the given DefaultListableBeanFactory.
       * @param beanFactory the DefaultListableBeanFactory instance to use for this context
       * @see #registerBeanDefinition
       * @see #refresh
       */
      public GenericApplicationContext(DefaultListableBeanFactory beanFactory) {
      	Assert.notNull(beanFactory, "BeanFactory must not be null");
      	this.beanFactory = beanFactory;
      }
    

    可以发现,是在父类将 this.beanFactory 赋值,不用这个构造就是直接 new 一个默认的。

  • public AnnotationConfigApplicationContext(Class<?>... componentClasses)

    以多个 class 为参数
    public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
      	this();
      	register(componentClasses);
      	refresh();
      }
    
    private static void test3(){
      	ApplicationContext context = new AnnotationConfigApplicationContext(TestBean.class, DogBean.class);
    
      	TestBean bean = context.getBean(TestBean.class);
      	bean.helloSpring();
    
      	DogBean dog = context.getBean(DogBean.class);
      	dog.say();
    }
    

    相当于无参构造 + register() + refresh(),这里参数 TestBean,可以是普通的 pojo 类,无需有 @Component 注解

  • public AnnotationConfigApplicationContext(String... basePackages)

    以多个包路径为参数
    public AnnotationConfigApplicationContext(String... basePackages) {
    		this();
    		scan(basePackages);
    		refresh();
    	}
    
    private static void test4(){
      	ApplicationContext context = new AnnotationConfigApplicationContext("org.springframework.component");
    
      	TestBean bean = context.getBean(TestBean.class);
      	bean.helloSpring();
    
      	DogBean dog = context.getBean(DogBean.class);
      	dog.say();
    }
    

    相当于无参构造 + scan() + refresh()

3. 过程解析

通过对构造方法的解析,可以确定有以下几个过程:

    1. super(beanFactory) 父类的构造方法
    1. new AnnotationConfigApplicationContext() 初始化容器
    1. register() 注册指定的类
    1. scan() 扫描类路径
    1. refresh() 刷新容器

1. 父类构造方法

执行子类构造方法时,会先执行父类构造方法,也就是this()方法的执行会先去执行父类的构造方法,那么就先从父类构造方法看起

AnnotationConfigApplicationContext继承自GenericApplicationContext

public GenericApplicationContext() {
	/**
	 * 初始化一个工厂类,用于创建bean对象
	 * @reviewer wangcongming
	 */
	this.beanFactory = new DefaultListableBeanFactory();
}

public GenericApplicationContext(DefaultListableBeanFactory beanFactory) {
	Assert.notNull(beanFactory, "BeanFactory must not be null");
    //直接赋值工厂类
	this.beanFactory = beanFactory;
}

初始化了一个工厂类 DefaultListableBeanFactory,几个重要属性:

/**
 * 用于排序
 * @reviewer wangcongming
 */
@Nullable
private Comparator<Object> dependencyComparator;
 
/**
 * 自动注入解析器
 * @reviewer wangcongming
 */
private AutowireCandidateResolver autowireCandidateResolver = new SimpleAutowireCandidateResolver();
 
/**
 * 依赖
 * @reviewer wangcongming
 */
private final Map<Class<?>, Object> resolvableDependencies = new ConcurrentHashMap<>(16);
 
/**
 * spring核心,用于存放BeanDefinition(描述bean的类)
 * @reviewer wangcongming
 */
private final Map<String, BeanDefinition> beanDefinitionMap = new ConcurrentHashMap<>(256);
 
/**
 * class与bean name映射关系
 * @reviewer wangcongming
 */
private final Map<Class<?>, String[]> allBeanNamesByType = new ConcurrentHashMap<>(64);
 
/**
 * 单例 class与bean name映射关系
 * @reviewer wangcongming
 */
private final Map<Class<?>, String[]> singletonBeanNamesByType = new ConcurrentHashMap<>(64);
 
/**
 * 用于存放bean name
 * @reviewer wangcongming
 */
private volatile List<String> beanDefinitionNames = new ArrayList<>(256);

总之这一步的作用就是,AnnotationConfigApplicationContext 示例持有一个 DefaultListableBeanFactory 实例

2. AnnotationConfigApplicationContext 初始化

public AnnotationConfigApplicationContext() {
	/**
	 * 初始化一个AnnotatedBeanDefinition读取器,用于读取被注解标注的bean,
	 * 读取的信息存放入AnnotatedBeanDefinition
	 */
	this.reader = new AnnotatedBeanDefinitionReader(this);
	/**
	 * 初始化一个扫描器,用于扫描类或者包下的所有类,将被注解标注的bean生成对应的AnnotatedBeanDefinition
	 */
	 this.scanner = new ClassPathBeanDefinitionScanner(this);
}

无参构造中只做了两件事,初始化一个读取器(AnnotatedBeanDefinitionReader)和一个扫描器(ClassPathBeanDefinitionScanner)

    1. 先看 new AnnotatedBeanDefinitionReader(this):读取注解生成BeanDefinition并注册

    AnnotatedBeanDefinitionReader 类构造方法

    public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry) {
    	this(registry, getOrCreateEnvironment(registry));
    }
    
    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);
    }
    

    AnnotationConfigUtils.registerAnnotationConfigProcessors() 最终调用:

    public static Set<BeanDefinitionHolder> registerAnnotationConfigProcessors(
      		BeanDefinitionRegistry registry, @Nullable Object source) {
    
      	/**
      	 * 从registry中获取DefaultListableBeanFactory
      	 * */
      	DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
      	if (beanFactory != null) {
      		/**
      		 * 初始化一个比较器
      		 * */
      		if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
      			beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
      		}
      		/**
      		 * 像是 Autowire 解析器
      		 * */
      		if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
      			beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
      		}
      	}
    
      	/**
      	 * 创建一个 Set,用于加入一些spring自己定义的bean,以便于后面初始化使用,完成一些功能。实际上在这里是没用用的,因为这个 set 返回了之后没用
      	 */
      	Set<BeanDefinitionHolder> beanDefs = new LinkedHashSet<>(8);
    
      	/**
      	 * ConfigurationClassPostProcessor用于读取配置类的
      	 */
      	if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
    
      		//创建一个 BeanDefinition
      		RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
      		def.setSource(source);
    
      		/**
      		 * new AnnotationConfigApplicationContext 这个分析中,其实用 registerPostProcessor 起作用的,beanDefs.add 没用
      		 */
      		beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
      	}
    
      	/**
      	 * AutowiredAnnotationBeanPostProcessor 用于处理依赖注入的
      	 * */
      	if (!registry.containsBeanDefinition(AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      		RootBeanDefinition def = new RootBeanDefinition(AutowiredAnnotationBeanPostProcessor.class);
      		def.setSource(source);
      		beanDefs.add(registerPostProcessor(registry, def, AUTOWIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
      	}
    
      	/**
      	 * 用于处理JSR-250支持
      	 * */
      	// Check for JSR-250 support, and if present add the CommonAnnotationBeanPostProcessor.
      	if (jsr250Present && !registry.containsBeanDefinition(COMMON_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      		RootBeanDefinition def = new RootBeanDefinition(CommonAnnotationBeanPostProcessor.class);
      		def.setSource(source);
      		beanDefs.add(registerPostProcessor(registry, def, COMMON_ANNOTATION_PROCESSOR_BEAN_NAME));
      	}
    
      	/**
      	 * 用于支持jpa的
      	 * */
      	// Check for JPA support, and if present add the PersistenceAnnotationBeanPostProcessor.
      	if (jpaPresent && !registry.containsBeanDefinition(PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME)) {
      		RootBeanDefinition def = new RootBeanDefinition();
      		try {
      			def.setBeanClass(ClassUtils.forName(PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME,
      					AnnotationConfigUtils.class.getClassLoader()));
      		}
      		catch (ClassNotFoundException ex) {
      			throw new IllegalStateException(
      					"Cannot load optional framework class: " + PERSISTENCE_ANNOTATION_PROCESSOR_CLASS_NAME, ex);
      		}
      		def.setSource(source);
      		beanDefs.add(registerPostProcessor(registry, def, PERSISTENCE_ANNOTATION_PROCESSOR_BEAN_NAME));
      	}
    
      	/**
      	 * 像是事件监听器
      	 * */
      	if (!registry.containsBeanDefinition(EVENT_LISTENER_PROCESSOR_BEAN_NAME)) {
      		RootBeanDefinition def = new RootBeanDefinition(EventListenerMethodProcessor.class);
      		def.setSource(source);
      		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_PROCESSOR_BEAN_NAME));
      	}
      	/**
      	 * 像是事件监听工厂
      	 * */
      	if (!registry.containsBeanDefinition(EVENT_LISTENER_FACTORY_BEAN_NAME)) {
      		RootBeanDefinition def = new RootBeanDefinition(DefaultEventListenerFactory.class);
      		def.setSource(source);
      		beanDefs.add(registerPostProcessor(registry, def, EVENT_LISTENER_FACTORY_BEAN_NAME));
      	}
    
      	return beanDefs;
      }
    

    (1)初始化 DependencyComparator 比较器
    (2)应该是 Autowired 解析器
    (3)注册了一些默认的 BeanDefinition 到 AnnotationConfigApplicationContext 持有的 registry 中。

    AnnotationConfigUtils.registerPostProcessor() 注册 beanDefinition

    private static BeanDefinitionHolder registerPostProcessor(
      	BeanDefinitionRegistry registry, RootBeanDefinition definition, String beanName) {
          
          //设置 beanDefinition 角色
      	definition.setRole(BeanDefinition.ROLE_INFRASTRUCTURE);
    
      	//通过 AnnotationConfigApplicationContext 的方法注入 beanDefinition
      	registry.registerBeanDefinition(beanName, definition);
      	return new BeanDefinitionHolder(definition, beanName);
    }
    

    DefaultListableBeanFactory.registerBeanDefinition():将 beanDefinition 注册到自己的 beanDefinitionMap 中

    /**
       * this.beanDefinitionMap.put(beanName, beanDefinition)
       * this.beanDefinitionNames.add(beanName)
       * */
      @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);
      				List<String> updatedDefinitions = 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);
      	}
      	else if (isConfigurationFrozen()) {
      		clearByTypeCache();
      	}
      }
    

    总结:AnnotationBeanDefinitionReader主要就是对Bean的描述(BeanDefinition)、获取当前的执行环境以及注册各种处理器。

    1. 再看 new ClassPathBeanDefinitionScanner(this):扫描类路径生成BeanDefinition并注册

    ClassPathBeanDefinitionScanner 构造方法:

    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry) {
    	this(registry, true);
    }
    
    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters) {
    	this(registry, useDefaultFilters, getOrCreateEnvironment(registry));
    }
    
    public ClassPathBeanDefinitionScanner(BeanDefinitionRegistry registry, boolean useDefaultFilters,
    		Environment environment) {
    	this(registry, useDefaultFilters, environment,
    			//判断容器类型,这里是 true
    			(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);
    	// 设置资源加载器(由前判断传来的BeanDefinitionRegistry)
    	setResourceLoader(resourceLoader);
    }
    

    用的是最后这个构造方法,设置环境,注册几个默认过滤器等。其中注册过滤器 registerDefaultFilters() 是调用父类的方法。

    ClassPathScanningCandidateComponentProvider.registerDefaultFilters():设置几个默认的过滤器

     //存储过滤器的
     private final List<TypeFilter> includeFilters = new LinkedList<>();
    
     /**
       * Register the default filter for {@link Component @Component}.
       * <p>This will implicitly register all annotations that have the
       * {@link Component @Component} meta-annotation including the
       * {@link Repository @Repository}, {@link Service @Service}, and
       * {@link Controller @Controller} stereotype annotations.
       * <p>Also supports Java EE 6's {@link javax.annotation.ManagedBean} and
       * JSR-330's {@link javax.inject.Named} annotations, if available.
       *
       * 主要想 this.includeFilters 中添加三个默认过滤器。
       * AnnotationTypeFilter(Component.class) 看样子是跟 @Component 有关的,@Service 等注解也是包含 @Component 的
       *
       * 后面两个则是 jsr-250 和 jsr-330 标准才有的,分别是 @ManagedBean 和 @Named
       */
      @SuppressWarnings("unchecked")
      protected void registerDefaultFilters() {
      	//添加一个过滤器,应该是跟 @Component 注解相关的
      	this.includeFilters.add(new AnnotationTypeFilter(Component.class));
      	//当前类加载器
      	ClassLoader cl = ClassPathScanningCandidateComponentProvider.class.getClassLoader();
      	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.
      		logger.error("JSR-250 1.1 API (as included in Java EE 6) not available");
      	}
      	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.
      		logger.error("JSR-330 API not available");
      	}
      }
    
    

    由于在这些有参构造中传递的第二个参数为true,即useDefaultFilters为true,所以就会进入到registerDefaultFilters()方法,从英文的理解可以猜测这个方法是注册默认的过滤器。此方法内就是寻找注解的类型,找到了就添加进 includeFilters 链表中,其中类型为 TypeFilter

    TypeFilter 类:

    @FunctionalInterface
    public interface TypeFilter {
    
     /**
       * Determine whether this filter matches for the class described by
       * the given metadata.
       * @param metadataReader the metadata reader for the target class
       * @param metadataReaderFactory a factory for obtaining metadata readers
       * for other classes (such as superclasses and interfaces)
       * @return whether this filter matches
       * @throws IOException in case of I/O failure when reading metadata
       *
       * 一看就是匹配筛选的。
       */
    boolean match(MetadataReader metadataReader, MetadataReaderFactory metadataReaderFactory)
      	throws IOException;
    
    }
    

    总结:ClassPathBeanDefinitionScanner 扫描器,就是设置环境与资源加载器,并且最主要的是获取被@Component注解的类。

3. register()

使用第二步骤初始化的 this.reader = new AnnotatedBeanDefinitionReader(this) 来注册指定的类

@Override
public void register(Class<?>... componentClasses) {
	Assert.notEmpty(componentClasses, "At least one component class must be specified");
    //注册指定的类
	this.reader.register(componentClasses);
}

AnnotatedBeanDefinitionReader.register 来实现注册

public void register(Class<?>... componentClasses) {
	for (Class<?> componentClass : componentClasses) {
		registerBean(componentClass);
	}
}

public void registerBean(Class<?> beanClass) {
	doRegisterBean(beanClass, null, null, null, null);
}

//这里开始真正一个一个的 beanClass 注册
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
		@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
		@Nullable BeanDefinitionCustomizer[] customizers) {

	/**
	 * 将传入的 beanClass 封装成一个 beanDefinition
	 * */
	AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);

	/**
	 * 对 @Conditional 注解的判断
	 * this.conditionEvaluator 在构造方法中初始化了,用来判断是否跳过是否注册
	 */
	if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
		return;
	}

	/**
	 * 暂时不知道这个属性是啥
	 */
	abd.setInstanceSupplier(supplier);

	/**
	 * bean 的 scope 属性,也就是作用域
	 * */
	ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
	abd.setScope(scopeMetadata.getScopeName());

	/**
	 * ❶ 生成 beanName
	 * */
	String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));

	/**
	 * 根据 beanDefinition.metadata 元数据信息,设置一系列的属性,比如懒加载 lazy,作用域 scope 等
	 * */
	AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);

	/**
	 * 因为这个参数是 null,这里暂时用不着,目前不知道干啥的
	 * */
	if (qualifiers != null) {
		for (Class<? extends Annotation> qualifier : qualifiers) {
			if (Primary.class == qualifier) {
				abd.setPrimary(true);
			}
			else if (Lazy.class == qualifier) {
				abd.setLazyInit(true);
			}
			else {
				abd.addQualifier(new AutowireCandidateQualifier(qualifier));
			}
		}
	}

	/**
	 * 因为这个参数是 null,这里暂时用不着,目前不知道干啥的
	 * */
	if (customizers != null) {
		for (BeanDefinitionCustomizer customizer : customizers) {
			customizer.customize(abd);
		}
	}

	/**
	 * 将处理好的 beanDefinition 封装成 BeanDefinitionHolder,没啥操作,就组装在一起
	 * */
	BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);

	/**
	 * 根据 scope 中的内容,是否要搞个 scope 代理
	 * */
	definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

	/**
	 * ❷ 注册 BeanDefinition
	 * */
	BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
  • ① beanName 的生成,根据注解获取,获取不到就类名,首字母小写
  • ② 注册 beanDefinition,

BeanDefinitionReaderUtils 注册 BeanDefinition 过程

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

	/**
	 * ❶ 注册 BeanDefinition,主要是添加到 BeanDefinitionMap 和 beanDefinitionNames 中
	 * */
	String beanName = definitionHolder.getBeanName();
	registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition());

	/**
	 * 别名处理,目前没遇到过
	 * */
	String[] aliases = definitionHolder.getAliases();
	if (aliases != null) {
		for (String alias : aliases) {
			registry.registerAlias(beanName, alias);
		}
	}
}
  • ① 调用容器的注册方法

DefaultListableBeanFactory.registerBeanDefinition() 真正的注册逻辑

@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);
		}
	}

	/**
	 * 根据 BeanName 从 beanDefinitionMap 获取 BeanDefinition
	 * */
	BeanDefinition existingDefinition = this.beanDefinitionMap.get(beanName);

	/**
	 * 当这个 bean 已经存在时的处理
	 * */
	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 + "]");
			}
		}

		/**
		 * 此时就相当于覆盖掉了原来的 bean
		 * */
		this.beanDefinitionMap.put(beanName, beanDefinition);
	}
	else {
		/**
		 * 看名字是 bean 是否被创建过
		 * todo alreadyCreated 暂不知道哪里用到
		 * */
		if (hasBeanCreationStarted()) {
			// Cannot modify startup-time collection elements anymore (for stable iteration)
			/**
			 *
			 * */
			synchronized (this.beanDefinitionMap) {
				/**
				 * 添加到 beanDefinitionMap
				 * */
				this.beanDefinitionMap.put(beanName, beanDefinition);
				/**
				 * 没太看懂这一步图啥,反正把名字加入 beanDefinitionNames
				 * */
				List<String> updatedDefinitions = new ArrayList<>(this.beanDefinitionNames.size() + 1);
				updatedDefinitions.addAll(this.beanDefinitionNames);
				updatedDefinitions.add(beanName);
				this.beanDefinitionNames = updatedDefinitions;
				/**
				 * todo 暂时不知道干啥的
				 * */
				removeManualSingletonName(beanName);
			}
		}
		else {
			// Still in startup registration phase
			/**
			 * 也是加入到两个集合中,跟正常流程相比,应该是覆盖
			 * */
			this.beanDefinitionMap.put(beanName, beanDefinition);
			this.beanDefinitionNames.add(beanName);
			removeManualSingletonName(beanName);
		}

		/**
		 * todo 冻结 beanName 啥的,看不懂
		 * */
		this.frozenBeanDefinitionNames = null;
	}

	/**
	 * 存在这个 beanDefinition,或者这个单例 bean 存在
	 * */
	if (existingDefinition != null || containsSingleton(beanName)) {
		/**
		 * 重置一下这个 beanDefinition
		 * */
		resetBeanDefinition(beanName);
	}
	else if (isConfigurationFrozen()) {
		/**
		 * 这也看不太懂,目前是走不到这里的
		 * */
		clearByTypeCache();
	}
}

这个过程,比较重要的就是两个 this.beanDefinitionMap.put(beanName, beanDefinition);this.beanDefinitionNames.add(beanName);

总结:
register() 这一过程,就是将指定的 Class 封装成 BeanDefinition,放到 beanDefinitionMap 中, beanName 放到 beanDefinitionNames 中。

posted @ 2024-08-23 15:18  primaryC  阅读(18)  评论(0编辑  收藏  举报