Spring源碼閱讀 (二):Bean 的生命週期.AnnotationConfigApplicationContext

1.建一個測試model

在源碼項目裏新建一個model,源碼編譯參考上一篇

建完model後在java包下添加三個類,執行成功就可以了就可以開始進行源碼閱讀了

這裏提一下還有一個ClassPathXmlApplicationContext,這個就是通過上下文去初始化Spring環境

public class Test {
	public static void main(String[] args) {
	    //註解去初始化Spring環境
		AnnotationConfigApplicationContext applicationContext =
				new AnnotationConfigApplicationContext(MyAppConfig.class);
		System.out.println(applicationContext.getBean(CityService.class));
	}
}

@Configuration
@ComponentScan("com.demo.spring")
public class MyAppConfig {
}

@Component
public class CityService {
}

Bean的生命週期

首先我們使用IDEA點進去看一下AnnotationConfigApplicationContext,這個就是通過註解來配置Spring的上下文環境

//載入解析註冊的過程

	public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
		//父類構造函數裏,創建了一個Bean工廠
		// this.beanFactory = new DefaultListableBeanFactory()
		this();
		//讀取和掃描器,將BeanDefinition方到Map裏
		register(annotatedClasses);

		refresh();
	}

1.首先是this方法,this方法幹了一個什麼事情呢?
首先這個無參構造方法裏面呢

        public  AnnotationConfigApplicationContext() {
        //創建一個讀取Bean定義的處理器,BeanDefinition
		this.reader = new AnnotatedBeanDefinitionReader(this);
		//掃描類轉換成BD
		//僅僅爲了程序員去使用AnnotationConfigApplicationContext
		this.scanner = new ClassPathBeanDefinitionScanner(this);
	}

調用子類構造方法也會調用父類構造方法

public GenericApplicationContext() {
         //實例化一個工廠
		this.beanFactory = new DefaultListableBeanFactory();
	}

Spring工廠:
理論:產生Bean
如果Bean實現了BeanNameAware接口,工廠調用Bean的setBeanName()方法傳遞Bean的ID。(和下面的一條均屬於檢查Aware接口)
如果Bean實現了BeanFactoryAware接口,工廠調用setBeanFactory()方法傳入工廠自身

2.之後是register(annotatedClasses);方法他做了什麼呢
將傳入的appConfig.class變成BeanDefinition

<T> void doRegisterBean(Class<T> annotatedClass, @Nullable Supplier<T> instanceSupplier, @Nullable String name,
			@Nullable Class<? extends Annotation>[] qualifiers, BeanDefinitionCustomizer... definitionCustomizers) {
		//根據指定的Bean創建一個AnnotatedGenericBeanDefinition
		//這個AnnotatedGenericBeanDefinition可以理解爲一個數據結構
		//包含了類的其他信息
		AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(annotatedClass);
		//判斷這個類是否要跳過解析
		if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
			return;
		}

		abd.setInstanceSupplier(instanceSupplier);
		//得到類的作用域
		ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
		//類的作用域添加到數據結構的結構當中
		abd.setScope(scopeMetadata.getScopeName());
		//生產Bean的名字
		String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
		//如果想容器註冊註解定義時,使用了額外的限定符註解則解析
		//qualifiers是包含了註解數組
		AnnotationConfigUtils.processCommonDefinitionAnnotations(abd);
		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 {
					abd.addQualifier(new AutowireCandidateQualifier(qualifier));
				}
			}
		}
		for (BeanDefinitionCustomizer customizer : definitionCustomizers) {
			customizer.customize(abd);
		}
		//也是一個數據結構
		BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
		definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
		//就是把definitionHolder一個DefaultListableFactory,registry就是ApplicationContext
		//點進代碼看到map.put
		BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
	}

3.最後是refresh();這個是SpringFramework裏一個主要的代碼說是最主要也不爲過。這裏呢一共調用了12個方法

@Override
	public void refresh() throws BeansException, IllegalStateException {
		//同步的方法
		synchronized (this.startupShutdownMonitor) {

			// 1.Prepare this context for refreshing.
			prepareRefresh();

			// 2.Tell the subclass to refresh the internal bean factory.
			// 刷新beanFactory,刪除舊的beanFactory,創建新的beanFactory
			ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

			// 3.Prepare the bean factory for use in this context.
			//準備bean工廠以供在此上下文中使用。
			prepareBeanFactory(beanFactory);

			try {
				// 4.Allows post-processing of the bean factory in context subclasses.
				//允許在上下文子類中對bean工廠進行後處理。
				postProcessBeanFactory(beanFactory);

				// 5.Invoke factory processors registered as beans in the context.
				// 調用工廠處理器,解析類信息 生成Bean
				// 執行自定義的processBean ,掃描Bean 處理了import
				// 掃描->putMap(RootBeanDefinition)->(1.custom)
				// 程序員可以,先處理自定義的,先處理order的

				invokeBeanFactoryPostProcessors(beanFactory);

				// 6Register bean processors that intercept bean creation.
				//註冊BeanPostProcessor前後
				registerBeanPostProcessors(beanFactory);

				// 7Initialize message source for this context.
				initMessageSource();

				// 8Initialize event multicaster for this context.
				initApplicationEventMulticaster();

				// 9Initialize other special beans in specific context subclasses.
				onRefresh();

				// 10Check for listener beans and register them.
				registerListeners();

				// 11Instantiate all remaining (non-lazy-init) singletons.
				// 實例化
				finishBeanFactoryInitialization(beanFactory);

				// Last step: publish corresponding event.
				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();
			}
		}
	}

(1)prepareRefresh();
//啓動事件標識位
// 設置環境變量和容器的開關標誌

(2)ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//要對工廠進行初始化

(3)準備工廠

(4)postProcessBeanFactory(beanFactory);
//允許在上下文子類中對bean工廠進行後處理。

(5)invokeBeanFactoryPostProcessors(beanFactory);

  1.掃描了符合要求的class文件,各種Import註解
2.解析成BeanDefinition
ps:之前的register也是掃描 但是放入了appConfig.class 也就是AnnotationConfigApplicationContext傳入的配置類
3.put->BeanDefinitionMap->調用自定義的BeanFactoryPostProcesser,還有內置的。
/**
 * 擴展原理:
 * BeanPostProcessor:bean後置處理器,bean創建對象初始化前後進行攔截工作的
 * 
 * 1、BeanFactoryPostProcessor:beanFactory的後置處理器;
 *         在BeanFactory標準初始化之後調用,來定製和修改BeanFactory的內容;
 *         所有的bean定義已經保存加載到beanFactory,但是bean的實例還未創建
 * 
 * 
 * BeanFactoryPostProcessor原理:
 * 1)、ioc容器創建對象
 * 2)、invokeBeanFactoryPostProcessors(beanFactory);
 *         如何找到所有的BeanFactoryPostProcessor並執行他們的方法;
 *             1)、直接在BeanFactory中找到所有類型是BeanFactoryPostProcessor的組件,並執行他們的方法
 *             2)、在初始化創建其他組件前面執行
 * 
 * 2、BeanDefinitionRegistryPostProcessor extends BeanFactoryPostProcessor
 *         postProcessBeanDefinitionRegistry();
 *         在所有bean定義信息將要被加載,bean實例還未創建的時候;
 *         優先於BeanFactoryPostProcessor執行;
 *         利用BeanDefinitionRegistryPostProcessor給容器中再額外添加一些組件;
 * 
 *     原理:
 *         1)、ioc創建對象
 *         2)、refresh()-》invokeBeanFactoryPostProcessors(beanFactory);
 *         3)、從容器中獲取到所有的BeanDefinitionRegistryPostProcessor組件。
 *             1、依次觸發所有的postProcessBeanDefinitionRegistry()方法
 *             2、再來觸發postProcessBeanFactory()方法BeanFactoryPostProcessor;
 * 
 *         4)、再來從容器中找到BeanFactoryPostProcessor組件;然後依次觸發postProcessBeanFactory()方法
 *     

(11)finishBeanFactoryInitialization(beanFactory);
實例化也就是new
beanFactory.preInstantiateSingletons();

//log級別
		if (logger.isDebugEnabled()) {
			logger.debug("Pre-instantiating singletons in " + this);
		}
		//所有Bean的名字
		// Iterate over a copy to allow for init methods which in turn register new bean definitions.
		// While this may not be part of the regular factory bootstrap, it does otherwise work fine.
		List<String> beanNames = new ArrayList<>(this.beanDefinitionNames);

		// Trigger initialization of all non-lazy singleton beans...
		//觸發所有非懶加載的單例Beans
		for (String beanName : beanNames) {
            //bdmap.get
			RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);
			if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {
				if (isFactoryBean(beanName)) {
					Object bean = getBean(FACTORY_BEAN_PREFIX + beanName);
					if (bean instanceof FactoryBean) {
						final FactoryBean<?> factory = (FactoryBean<?>) bean;
						boolean isEagerInit;
						if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {
							isEagerInit = AccessController.doPrivileged((PrivilegedAction<Boolean>)
											((SmartFactoryBean<?>) factory)::isEagerInit,
									getAccessControlContext());
						} else {
							isEagerInit = (factory instanceof SmartFactoryBean &&
									((SmartFactoryBean<?>) factory).isEagerInit());
						}
						if (isEagerInit) {
							getBean(beanName);
						}
					}
				} else {
					//實例Bean放到單例池裏 單例池是一個ConcuretHashMap
					getBean(beanName);
				}
			}
		}

		// Trigger post-initialization callback for all applicable beans...
		for (String beanName : beanNames) {
			Object singletonInstance = getSingleton(beanName);
			if (singletonInstance instanceof SmartInitializingSingleton) {
				final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;
				if (System.getSecurityManager() != null) {
					AccessController.doPrivileged((PrivilegedAction<Object>) () -> {
						smartSingleton.afterSingletonsInstantiated();
						return null;
					}, getAccessControlContext());
				} else {
					smartSingleton.afterSingletonsInstantiated();
				}
			}
		}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章