天天看點

深入淺出Spring源碼之IOC(一)深入淺出Spring源碼之IOC(一)

深入淺出Spring源碼之IOC(一)

目錄

深入淺出Spring源碼之IOC

前置知識

AnnotationConfigApplicationContext

register()注冊配置類

refresh()重新整理IOC容器

前置知識

IOC是Spring最核心部分,IOC即Inversion of Control,意為控制反轉,其為建立和提供bean的容器,讓程式編寫人員把這部分的建立和擷取bean對象的工作交給了Spring。先看一個需要了解的概念:BeanDefinition,顧名思義,它是一個定義bean的類。如果把bean看成是一輛汽車,那BeanDefinition就是汽車設計圖紙。Spring會根據BeanDefinition來建立bean。

then:

  • BeanDefinitionRegistryPostProcessor:向容器注冊BeanDefinition的接口。
  • BeanFactoryPostProcessor:擴充BeanDefinition的接口。
  • BeanPostProcessor:在建立bean的過程中調用的一系列接口。

AnnotationConfigApplicationContext是繼承自BeanFactory,是基于注解的Spring的應用上下文。現在的我們已經逐漸抛棄了基于xml的開發方式。

AnnotationConfigApplicationContext

下面從AnnotationConfigApplicationContext的入口開始進入IOC的加載流程:

AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
           

執行構造方法:

public AnnotationConfigApplicationContext() {
		/**
		 * 建立一個讀取注解的Bean定義讀取器
		 *
		 * 完成了spring内部BeanDefinition的注冊(主要是後置處理器)
		 */
		this.reader = new AnnotatedBeanDefinitionReader(this);
		/**
		 * 建立BeanDefinition掃描器
		 * 可以用來掃描包或者類,繼而轉換為BeanDefinition
		 *
		 * spring預設的掃描包不是這個scanner對象
		 * 而是自己new的一個ClassPathBeanDefinitionScanner
		 * spring在執行工程後置處理器ConfigurationClassPostProcessor時,去掃描包時會new一個ClassPathBeanDefinitionScanner
		 *
		 * 這裡的scanner僅僅是為了程式員可以手動調用AnnotationConfigApplicationContext對象的scan方法
		 *
		 */
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}
           

new AnnotatedBeanDefinitionReader(this):

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;
		//ConditionEvaluator用來處理條件配置 @Conditional
		this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
		//這裡注冊一些内置的後置處理器
		AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
	}
           

AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry):

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


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

		DefaultListableBeanFactory beanFactory = unwrapDefaultListableBeanFactory(registry);
		if (beanFactory != null) {
			if (!(beanFactory.getDependencyComparator() instanceof AnnotationAwareOrderComparator)) {
				//注冊了實作Order接口的排序器
				beanFactory.setDependencyComparator(AnnotationAwareOrderComparator.INSTANCE);
			}
			//設定@AutoWired的候選的解析器:ContextAnnotationAutowireCandidateResolver
			// getLazyResolutionProxyIfNecessary方法,它也是唯一實作。
			//如果字段上帶有@Lazy注解,表示進行懶加載 Spring不會立即建立注入屬性的執行個體,而是生成代理對象,來代替執行個體
			if (!(beanFactory.getAutowireCandidateResolver() instanceof ContextAnnotationAutowireCandidateResolver)) {
				beanFactory.setAutowireCandidateResolver(new ContextAnnotationAutowireCandidateResolver());
			}
		}

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

		/**
		 * 為我們容器中注冊了解析我們配置類的後置處理器ConfigurationClassPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalConfigurationAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(ConfigurationClassPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, CONFIGURATION_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 為我們容器中注冊了處理@Autowired 注解的處理器AutowiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalAutowiredAnnotationProcessor
		 */
		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));
		}

		/**
		 * 為我們容器中注冊處理@Required屬性的注解處理器RequiredAnnotationBeanPostProcessor
		 * 名字叫:org.springframework.context.annotation.internalRequiredAnnotationProcessor
		 */
		if (!registry.containsBeanDefinition(REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME)) {
			RootBeanDefinition def = new RootBeanDefinition(RequiredAnnotationBeanPostProcessor.class);
			def.setSource(source);
			beanDefs.add(registerPostProcessor(registry, def, REQUIRED_ANNOTATION_PROCESSOR_BEAN_NAME));
		}

		/**
		 * 為我們容器注冊處理JSR規範的注解處理器CommonAnnotationBeanPostProcessor
		 * org.springframework.context.annotation.internalCommonAnnotationProcessor
		 */
		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注解的處理器org.springframework.orm.jpa.support.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));
		}

		/**
		 * 處理監聽方法的注解@EventListener解析器EventListenerMethodProcessor
		 */
		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;
	}
           

register()注冊配置類

接下來,注冊配置類的beanDefinition,ctx.register(Class<?>... annotatedClasses):

public void register(Class<?>... annotatedClasses) {
		Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
		this.reader.register(annotatedClasses);
	}


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


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

這是一系列調用鍊,最後會進入doRegisterBean(annotatedClass, null, null, null):

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
		//存儲@Configuration注解注釋的類
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		//判斷是否需要跳過注解,spring中有一個@Condition注解,當不滿足條件,這個bean就不會被解析
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(instanceSupplier);
		//解析bean的作用域,如果沒有設定的話,預設為單例
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		abd.setScope(scopeMetadata.getScopeName());
		//獲得beanName
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		//解析通用注解,填充到AnnotatedGenericBeanDefinition,解析的注解為Lazy,Primary,DependsOn,Role,Description
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		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));
				}
			}
		}
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}

		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
        //設定bean的代理模式,這裡可指定cglib代理
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);

		//注冊,最終會調用DefaultListableBeanFactory中的registerBeanDefinition方法去注冊,
		//DefaultListableBeanFactory維護着一系列資訊,比如beanDefinitionNames,beanDefinitionMap
		//beanDefinitionNames是一個List<String>,用來儲存beanName
		//beanDefinitionMap是一個Map,用來儲存beanName和beanDefinition
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}
           

refresh()重新整理IOC容器

接下來,重新整理IOC容器,這裡會建立一系列的bean并放入IOC容器ctx.refresh():

@Override
	public void refresh() throws BeansException, IllegalStateException {
		synchronized (this.startupShutdownMonitor) {
			//準備重新整理上下文環境
			prepareRefresh();

			//擷取告訴子類初始化Bean工廠  不同工廠不同實作
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			//對bean工廠進行填充屬性
			prepareBeanFactory(beanFactory);

			try {
				// 留個子類去實作該接口
				postProcessBeanFactory(beanFactory);

				// 調用我們的bean工廠的後置處理器,會在此将class掃描成beanDefinition  2.bean工廠的後置處理器調用
				invokeBeanFactoryPostProcessors(beanFactory);

				// 注冊我們bean的後置處理器
				registerBeanPostProcessors(beanFactory);

				// 初始化國際化資源處理器.
				initMessageSource();

				// 建立事件多點傳播器
				initApplicationEventMulticaster();

				// 這個方法同樣也是留個子類實作的springboot也是從這個方法進行啟動tomcat的.
				onRefresh();

				//把我們的事件監聽器注冊到多點傳播器上
				registerListeners();

				// 執行個體化我們剩餘的單執行個體bean.
				finishBeanFactoryInitialization(beanFactory);

				// 最後容器重新整理 釋出重新整理事件(Spring cloud也是從這裡啟動的)
				finishRefresh();
			}

			catch (BeansException ex) {
				if (logger.isWarnEnabled()) {
					logger.warn("Exception  encountered during context initialization - " +
							"cancelling refresh attempt: " + ex);
				}

				// Destroy already created singletons to avoid dangling resources.
				destroyBeans();

				// Reset 'active' flag.
				cancelRefresh(ex);

				// Propagate exception to caller.
				throw ex;
			}

			finally {
				// Reset common introspection caches in Spring's core, since we
				// might not ever need metadata for singleton beans anymore...
				resetCommonCaches();
			}
		}
	}