spring-ioc源码

一句话

AnnotationConfigApplicationContext context= new AnnotationConfigApplicationContext(MainConfig.class);

IOC容器的初始化,通过这样一句话完成。加载入我们的配置类 MainConfig.class 这里我们采用的是注解配置类的方式。

一分三

进入到源码中,new AnnotationConfigApplicationContext(),究竟做了哪些事?

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//调用构造函数
		this();
		//注册我们的配置类
		register(annotatedClasses);
		//IOC容器刷新接口
		refresh();
	}

这里可以看到,调用AnnotationConfigApplicationContext的构造方法,里面有这样的三句话。关于这三句的大致完成的事注释已经写清。下面就分别进行细抠一下,具体完成的事情。

调用构造函数

这里提一下,AnnotationConfigApplicationContext是继承自GenericApplicationContext,会默认调用父类的构造函数

public GenericApplicationContext() {
		/**
		 * 调用父类的构造函数,为ApplicationContext spring上下文对象初始beanFactory
		 * 为啥是DefaultListableBeanFactory?我们去看BeanFactory接口的时候
		 * 发DefaultListableBeanFactory是最底层的实现,功能是最全的
		 */
		this.beanFactory = new DefaultListableBeanFactory();
	}

public AnnotationConfigApplicationContext() {
		/**
		 * 初始化注解模式下的bean定义扫描器
		 * 调用AnnotatedBeanDefinitionReader构造方法,传入的是this(AnnotationConfigApplicationContext)对象
		 */
		//注册内置BeanPostProcessor以及注册相关的BeanDefinition
		this.reader = new AnnotatedBeanDefinitionReader(this);
		/**
		 * 初始化我们的classPath类型的bean定义扫描器
		 */
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

首先是父类的构造函数,这里就实例化了一个BeanFactory。值得一提的是,整个spring框架中有很多个BeanFactory,他们根据各自继承体系的不同,在框架中担任不同的任务,当然后面提到的BeanDefinition也是这样,之后再对这些个玩意细抠一下。ok,来看一下这个BeanFactory的继承关系

在这里插入图片描述

这里先记住,调用父类构造器实例化了一个DefaultListableBeanFactory。

接着走,在Annotation的构造器中实例化了两个,一个是Bean定义的reader,一个是扫描器。后者是我们手动添加扫描的时候才会调用到,这里并不会。我们直接看第一个。

public AnnotatedBeanDefinitionReader(BeanDefinitionRegistry registry, Environment environment) {
		Assert.notNull(registry, "BeanDefinitionRegistry must not be null");
		Assert.notNull(environment, "Environment must not be null");
		//把ApplicationContext对象赋值给AnnotatedBeanDefinitionReader
		this.registry = registry;
		//用户处理条件表达式计算 @Conditionl
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		//注册一些配置的后置处理器
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}

这里完成了三件:

  • 首先是将BeanDefinitionRegistry赋值给此处的bean定义reader中,这个BeanDefinitionRegistry实际上就是刚刚的AnnotationConfigApplicationContext
  • 然后实例化处理条件计算@Condition注解的类
  • 最后,注册一些配置的后置处理器到beanDefinitionMap中共计6个

注册配置类

在AnnotationConfigApplicationContext的构造函数中,将我们的配置类作为参数调用register方法

直接跟到AnnotatedBeanDefinitionReader中

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
		//这里将配置类包装为一个BeanDefinition。
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
    	    //通过获取元注解,判断是否含有Condition注解,有的话直接返回
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}
		
		abd.setInstanceSupplier(instanceSupplier);
    		//保证缺省情况下,是单例模式
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
    	    //这里获取beanName,根据注解@componet系列的生成beanName,如果一个类上有两个@Component系注解,而且名字bean名字不同,这里就会报错
    	   //例如 @Service("car1")  @Component("car2")
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		//处理bean定义中的5个通用注解:lazy、primary、DependsOn、Role、Description
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
                //这段if逻辑,针对的是Qualifier注解,
		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));
				}
			}
		}
                 //这段代码是spring5.0以后新加入的,Spring 5允许使用lambda 表达式来自定义注册一个 bean,具体操作我并不太清楚
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}
		//这里将beanName同配置类的包装类bean定义一起,封装为一个Holder。相当于是一个bean定义的持有者。
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
    	//这里通过注解工具类,获取到我们配置类上的@Scope注解内容。使用的是proxyMode属性设置的,默认为NO,也就是没有代理
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
            //开始注册bean定义了
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

进入到注册bean定义的流程

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

		// Register bean definition under primary name.
		String beanName = definitionHolder.getBeanName();
		registry.registerBeanDefinition(beanName, definitionHolder.getBeanDefinition()); //将配置类注册到beanDefinitionMap中

		// Register aliases for bean name, if any.
		String[] aliases = definitionHolder.getAliases();
		if (aliases != null) {
			for (String alias : aliases) {
				registry.registerAlias(beanName, alias);
			}
		}
	}

//defaultListableBeanFactory类中
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 oldBeanDefinition;
 
   oldBeanDefinition = this.beanDefinitionMap.get(beanName);
   if (oldBeanDefinition != null) {
      if (!isAllowBeanDefinitionOverriding()) {
         throw new BeanDefinitionStoreException(beanDefinition.getResourceDescription(), beanName,
               "Cannot register bean definition [" + beanDefinition + "] for bean '" + beanName +
               "': There is already [" + oldBeanDefinition + "] bound.");
      }
      else if (oldBeanDefinition.getRole() < beanDefinition.getRole()) {
         // e.g. was ROLE_APPLICATION, now overriding with ROLE_SUPPORT or ROLE_INFRASTRUCTURE
         if (this.logger.isWarnEnabled()) {
            this.logger.warn("Overriding user-defined bean definition for bean '" + beanName +
                  "' with a framework-generated bean definition: replacing [" +
                  oldBeanDefinition + "] with [" + beanDefinition + "]");
         }
      }
      else if (!beanDefinition.equals(oldBeanDefinition)) {
         if (this.logger.isInfoEnabled()) {
            this.logger.info("Overriding bean definition for bean '" + beanName +
                  "' with a different definition: replacing [" + oldBeanDefinition +
                  "] with [" + beanDefinition + "]");
         }
      }
      else {
         if (this.logger.isDebugEnabled()) {
            this.logger.debug("Overriding bean definition for bean '" + beanName +
                  "' with an equivalent definition: replacing [" + oldBeanDefinition +
                  "] 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;
            if (this.manualSingletonNames.contains(beanName)) {
               Set<String> updatedSingletons = new LinkedHashSet<>(this.manualSingletonNames);
               updatedSingletons.remove(beanName);
               this.manualSingletonNames = updatedSingletons;
            }
         }
      }
      else {
         // Still in startup registration phase
         this.beanDefinitionMap.put(beanName, beanDefinition);
         this.beanDefinitionNames.add(beanName);
         this.manualSingletonNames.remove(beanName);
      }
      this.frozenBeanDefinitionNames = null;
   }
 
   if (oldBeanDefinition != null || containsSingleton(beanName)) {
      resetBeanDefinition(beanName);
   }
}

关键点在最后几行,86~88。将配置类放到了Map中,现在Map中有7个类。

本篇文章只是对大致的流程进行讲解,细节还是没有搞到位的,学习还是日益精进吧。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值