前言介紹
本篇文章篇幅較大,希望讀者可以慢慢閱讀,建議收藏悬垃,分多次閱讀學(xué)習(xí)游昼。
-
學(xué)習(xí)源碼的過程當(dāng)中,有幾點(diǎn)建議:
一定要學(xué)會抓重點(diǎn)尝蠕,歸納核心類烘豌、核心方法、核心步驟看彼;
分析源碼我們不需要太過于糾結(jié)細(xì)節(jié)廊佩,不然,這個源碼最起碼得分析月才能分析完靖榕;
主要的目的是分析整個容器初始化過程标锄,怎么初始化bean,怎么設(shè)置動態(tài)代理茁计;我們主要學(xué)習(xí)的是他們的思想料皇,以及代碼中運(yùn)用到的設(shè)計(jì)模式;
容器框架重要對象
BeanFactory:用于訪問容器中bean的接口星压,使用的是工廠模式践剂,重點(diǎn)注意DefaultListableBeanFactory,是貫穿的整個容器的基本工廠類租幕。
BeanDefinition:BeanDefinition是bean在Spring中的描述舷手,先讀取到bean的各種元素,然后利用BeanDefinition去初始化bean劲绪,是spring從起管理bean對象的數(shù)據(jù)模型。
BeanDefinitionRegistry接口:注冊bean定義到Spring容器中盆赤,與BeanFactory接口相對應(yīng)贾富,主要針對于Bean的注冊,BeanFactory主要針對于bean對象的管理牺六。
BeanFactoryPostProcessor接口:bean工廠后置處理器颤枪,該接口的作用主要是提供擴(kuò)展點(diǎn),用于各種bean定義的注冊和實(shí)例化等淑际,比較需要主要關(guān)注ConfigurationClassPostProcessor該類畏纲;
BeanPostProcessor接口:bean的后置處理器,該接口提供的擴(kuò)展點(diǎn)春缕,用于初始化bean盗胀,以及初始化完成后的各種擴(kuò)展;
IOC容器初始化的大致流程
首先讀取
BeanDefinition
放到容器中锄贼。通過BeanFactoryPostProcessor對象的擴(kuò)展
通過BeanPostProcessor對象的擴(kuò)展
然后根據(jù)BeanDefinition去初始化bean票灰。
最后實(shí)際進(jìn)行初始化然后保存到容器中。
來實(shí)現(xiàn)各種不同的功能;IOC容器初始化大致的一個流程屑迂,主要是看AnnotationConfigApplicationContext
和refresh
AnnotationConfigApplicationContext構(gòu)造器分析
傳入配置類的構(gòu)造函數(shù)
public AnnotationConfigApplicationContext(Class<?>... componentClasses) {
//初始化容器浸策,創(chuàng)建bean工廠,加載各種內(nèi)部重要類的bean定義惹盼,用于初始化我們或者其他引入類
this();
//注冊我們配置類的bean定義庸汗,初始化容器,從這個類開始
register(componentClasses);
//準(zhǔn)備工作做好后手报,開始初始化容器
refresh();
}
先看下this()這一行代碼
AnnotatedBeanDefinitionReader:主要用于讀取相關(guān)內(nèi)部的Spring容器的Bean對象夫晌。
public AnnotationConfigApplicationContext() {
//初始化讀取bean定義的讀取器,完成Spring內(nèi)部bean定義的注冊
this.reader = new AnnotatedBeanDefinitionReader(this);
//初始化一個類掃描器昧诱,其實(shí)這個方法進(jìn)來晓淀,是沒有用到這個掃描器的
this.scanner = new ClassPathBeanDefinitionScanner(this);
}
從上面創(chuàng)建bean定義讀取器,看下構(gòu)造方法
//從上面創(chuàng)建bean定義讀取器盏档,看下構(gòu)造方法
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");
//把ApplicationContext對象賦值給bean定義讀取器
this.registry = registry;
this.conditionEvaluator = new ConditionEvaluator(registry, environment, null);
//主要是看這個方法凶掰,注冊Spring內(nèi)部重要的bean定義
AnnotationConfigUtils.registerAnnotationConfigProcessors(this.registry);
}
到這里this(),這個方法流程就過完了蜈亩,主要就是注冊spring內(nèi)部重要的bean定義懦窘,來看下register(componentClasses)方法
//此目的主要針對于上面注冊的reader進(jìn)行注冊相關(guān)的bean
public void register(Class<?>... annotatedClasses) {
Assert.notEmpty(annotatedClasses, "At least one annotated class must be specified");
//使用上面初始化的bean定義讀取器,去注冊我們配置類的bean定義
this.reader.register(annotatedClasses);
}
//遍歷去注冊傳入進(jìn)來的注解相關(guān)的Bean對象
public void register(Class<?>... annotatedClasses) {
for (Class<?> annotatedClass : annotatedClasses) {
registerBean(annotatedClass);
}
}
//
public void registerBean(Class<?> annotatedClass) {
doRegisterBean(annotatedClass, null, null, null);
}
//注冊bean定義
private <T> void doRegisterBean(Class<T> beanClass, @Nullable String name,
@Nullable Class<? extends Annotation>[] qualifiers, @Nullable Supplier<T> supplier,
@Nullable BeanDefinitionCustomizer[] customizers) {
//根據(jù)配置類創(chuàng)建一個bean定義
AnnotatedGenericBeanDefinition abd = new AnnotatedGenericBeanDefinition(beanClass);
if (this.conditionEvaluator.shouldSkip(abd.getMetadata())) {
return;
}
abd.setInstanceSupplier(supplier);
//解析bean的作用域稚配,如果沒有設(shè)置畅涂,則默認(rèn)是單例
ScopeMetadata scopeMetadata = this.scopeMetadataResolver.resolveScopeMetadata(abd);
abd.setScope(scopeMetadata.getScopeName());
// 創(chuàng)建bean對象的bean名稱
String beanName = (name != null ? name : this.beanNameGenerator.generateBeanName(abd, this.registry));
//解析該bean是否有Lazy,Primary道川,DependsOn午衰,Description等注解,有則填充進(jìn)去
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));
}
}
}
if (customizers != null) {
for (BeanDefinitionCustomizer customizer : customizers) {
customizer.customize(abd);
}
}
// 構(gòu)建BeanDefinitionHolder對象去引用對象
BeanDefinitionHolder definitionHolder = new BeanDefinitionHolder(abd, beanName);
definitionHolder = AnnotationConfigUtils.applyScopedProxyMode(scopeMetadata, definitionHolder, this.registry);
//最后把該bean定義注冊到Bean工廠中去
BeanDefinitionReaderUtils.registerBeanDefinition(definitionHolder, this.registry);
}
register(componentClasses)冒萄,方法到此結(jié)束臊岸,然后我們分析refresh();方法,該方法初始化了IOC容器尊流。
public void refresh() throws BeansException, IllegalStateException {
synchronized (this.startupShutdownMonitor) {
//設(shè)置容器狀態(tài)帅戒,準(zhǔn)備刷新容器
prepareRefresh();
//獲取到容器的bean工廠
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
//填充bean工廠的各種屬性
prepareBeanFactory(beanFactory);
try {
//留給子類實(shí)現(xiàn),我們看的AnnotationConfigApplicationContext繼承了GenericApplicationContext崖技,該類主要是注冊了ServletContextAwareProcessor
postProcessBeanFactory(beanFactory);
//主要調(diào)用bean工廠的后置處理器逻住,把我們的類,注冊成bean定義
invokeBeanFactoryPostProcessors(beanFactory);
// 注冊 BeanPostProcessor 的實(shí)現(xiàn)類
// 此接口兩個方法: postProcessBeforeInitialization 和 postProcessAfterInitialization
// 兩個方法分別在 Bean 初始化之前和初始化之后得到執(zhí)行迎献。注意瞎访,到這里 Bean 還沒初始化
registerBeanPostProcessors(beanFactory);
//初始化國際化資源(這個方法不重要)
initMessageSource();
//Spring事件相關(guān),主要是創(chuàng)建一個事件多播器
initApplicationEventMulticaster();
//留給子類實(shí)現(xiàn)
onRefresh();
//把我們的事件注冊到容器中
registerListeners();
//實(shí)例化我們需要的bean忿晕,放入IOC容器
finishBeanFactoryInitialization(beanFactory);
//完成容器IOC容器初始化装诡,并且發(fā)布初始化完成事件
finishRefresh();
}
catch (BeansException ex) {
if (logger.isWarnEnabled()) {
logger.warn("Exception encountered during context initialization - " +
"cancelling refresh attempt: " + ex);
}
destroyBeans();
cancelRefresh(ex);
throw ex;
}
finally {
resetCommonCaches();
}
}
}
分析主要的步驟
- 首先 prepareRefresh():方法主要是為容器設(shè)置一個狀態(tài)(準(zhǔn)備工作银受,記錄下容器的啟動時間、標(biāo)記“已啟動”狀態(tài)鸦采、處理配置文件中的占位符)
- 然后接下來是獲取相應(yīng)的工廠類宾巍,AnnotationConfigApplicationContext主要是獲取到DefaultListableBeanFactory,但是如果是XML方式渔伯,會在該方法去加載bean定義顶霞,我們不分析這種方式
- 這步比較關(guān)鍵,這步完成后锣吼,配置文件/配置類就會解析成一個Bean定義选浑,注冊到 BeanFactory 中,
- 這里說的Bean還沒有初始化玄叠,只是配置信息都提取出來了古徒,
- 注冊也只是將這些信息都保存到了注冊中心(說到底核心是一個 beanName-> beanDefinition 的 map)
prepareRefresh() 創(chuàng)建容器前的準(zhǔn)備工作
protected void prepareRefresh() {
// 記錄啟動時間砰识,
// 將 active 屬性設(shè)置為 true撑刺,closed 屬性設(shè)置為 false,它們都是 AtomicBoolean 類型
this.startupDate = System.currentTimeMillis();
this.closed.set(false);
this.active.set(true);
if (logger.isInfoEnabled()) {
logger.info("Refreshing " + this);
}
// Initialize any placeholder property sources in the context environment
initPropertySources();
// 校驗(yàn) xml 配置文件
getEnvironment().validateRequiredProperties();
this.earlyApplicationEvents = new LinkedHashSet<ApplicationEvent>();
}
obtainFreshBeanFactory() 創(chuàng)建 Bean 容器述呐,加載并注冊 Bean
IoC初始化里面最重要的部分寺惫。
關(guān)鍵是以下幾步:
- 初始化BeanFactory
- 加載Bean
- 注冊Bean
注意:這步完成后疹吃,Bean 并沒有完成初始化,實(shí)際的實(shí)例并沒有被創(chuàng)建西雀。
AbstractApplicationContext#obtainFreshBeanFactory()
protected ConfigurableListableBeanFactory obtainFreshBeanFactory(){
// 關(guān)閉舊的 BeanFactory (如果有)萨驶,創(chuàng)建新的 BeanFactory,加載 Bean 定義艇肴、注冊 Bean 等等
refreshBeanFactory();
// 返回上一步剛剛創(chuàng)建的BeanFactory
ConfigurableListableBeanFactory beanFactory = getBeanFactory();
if (logger.isDebugEnabled()) {
logger.debug("Bean factory for " + getDisplayName() + ": " + beanFactory);
}
return beanFactory;
}
AbstractRefreshableApplicationContext#refreshBeanFactory()
protected final void refreshBeanFactory() throws BeansException {
// 如果 ApplicationContext 已經(jīng)加載過 BeanFactory腔呜,銷毀所有的Bean,關(guān)閉BeanFactory
// 注意點(diǎn):應(yīng)用中BeanFactory是可以有多個的豆挽,這里可不是說全局是否有BeanFactory
// 而是說當(dāng)前的ApplicationContext有沒有BeanFactory育谬!
if (hasBeanFactory()) {
destroyBeans();
closeBeanFactory();
}
try {
// 初始化一個 DefaultListableBeanFactory
DefaultListableBeanFactory beanFactory = createBeanFactory();
// 用于 BeanFactory 的序列化,一般人應(yīng)該用不到吧...
beanFactory.setSerializationId(getId());
// 下面是兩個重點(diǎn)方法
// 設(shè)置 BeanFactory 的兩個重要屬性
// 是否允許 Bean 覆蓋帮哈、是否允許循環(huán)引用
customizeBeanFactory(beanFactory);
// 加載BeanDefinition到BeanFactory 單獨(dú)拉出來講
loadBeanDefinitions(beanFactory);
synchronized (this.beanFactoryMonitor) {
this.beanFactory = beanFactory;
}
}
catch (IOException ex) {
throw new ApplicationContextException("I/O error parsing bean definition source for " + getDisplayName(), ex);
}
}
可以感覺到一個設(shè)計(jì)思路,ApplicationContext 繼承自 BeanFactory锰镀,但是它不應(yīng)該被理解為 BeanFactory 的實(shí)現(xiàn)類娘侍,而是說其內(nèi)部持有一個實(shí)例化的 BeanFactory(DefaultListableBeanFactory)。以后所有的 BeanFactory 相關(guān)的操作其實(shí)是委托給這個實(shí)例來處理的泳炉。
customizeBeanFactory
protected void customizeBeanFactory(DefaultListableBeanFactory beanFactory) {
if (this.allowBeanDefinitionOverriding != null) {
beanFactory.setAllowBeanDefinitionOverriding(this.allowBeanDefinitionOverriding);
}
if (this.allowCircularReferences != null) {
beanFactory.setAllowCircularReferences(this.allowCircularReferences);
}
}
BeanDefinition 的覆蓋問題可能會有開發(fā)者碰到這個坑憾筏,就是在配置文件中定義 bean 時使用了相同的 id 或 name。
默認(rèn)情況下花鹅,allowBeanDefinitionOverriding 屬性為 null(Boolean類型)氧腰,如果在同一配置文件中重復(fù)了,會拋錯,但是如果不是同一配置文件中古拴,會發(fā)生覆蓋箩帚。
循環(huán)引用也很好理解:A 依賴 B,而 B 依賴 A黄痪〗襞粒或 A 依賴 B,B 依賴 C桅打,而 C 依賴 A是嗜。
默認(rèn)情況下,Spring 允許循環(huán)依賴挺尾,當(dāng)然如果你在 A 的構(gòu)造方法中依賴 B鹅搪,在 B 的構(gòu)造方法中依賴 A 是不行的。
loadBeanDefinitions(beanFactory) 加載BeanDefinition
/**
* Load bean definitions into the given bean factory, typically through
* delegating to one or more bean definition readers.
* @param beanFactory the bean factory to load bean definitions into
* @throws BeansException if parsing of the bean definitions failed
* @throws IOException if loading of bean definition files failed
* @see org.springframework.beans.factory.support.PropertiesBeanDefinitionReader
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
*/
protected abstract void loadBeanDefinitions(DefaultListableBeanFactory beanFactory)
throws BeansException, IOException;
ClassPathXmlApplicationContext 是按照解析XML的加載方式遭铺±鍪粒看javadoc的描述,是通過
XmlBeanDefinitionReader
來載入Bean Definitions掂僵。
/**
* Loads the bean definitions via an XmlBeanDefinitionReader.
* @see org.springframework.beans.factory.xml.XmlBeanDefinitionReader
* @see #initBeanDefinitionReader
* @see #loadBeanDefinitions
*/
@Override
protected void loadBeanDefinitions(DefaultListableBeanFactory beanFactory) throws BeansException, IOException {
// Create a new XmlBeanDefinitionReader for the given BeanFactory.
XmlBeanDefinitionReader beanDefinitionReader = new XmlBeanDefinitionReader(beanFactory);
// Configure the bean definition reader with this context's
// resource loading environment.
beanDefinitionReader.setEnvironment(this.getEnvironment());
beanDefinitionReader.setResourceLoader(this);
beanDefinitionReader.setEntityResolver(new ResourceEntityResolver(this));
// Allow a subclass to provide custom initialization of the reader,
// 初始化Reader 不重要航厚,看下這個方法的javadoc就很好理解了
initBeanDefinitionReader(beanDefinitionReader);
// 真正重要的步驟!锰蓬!
// 用Reader去加載XML配置
loadBeanDefinitions(beanDefinitionReader);
}
loadBeanDefinitions(beanDefinitionReader)
/**
* Load the bean definitions with the given XmlBeanDefinitionReader.
* 看這句注釋:this method is just supposed to load and/or register bean definitions.
*/
protected void loadBeanDefinitions(XmlBeanDefinitionReader reader) throws BeansException, IOException {
Resource[] configResources = getConfigResources();
if (configResources != null) {
reader.loadBeanDefinitions(configResources);
}
String[] configLocations = getConfigLocations();
if (configLocations != null) {
// 這個分支幔睬,通過路徑名去獲取Resource,會和上面的方法殊途同歸
reader.loadBeanDefinitions(configLocations);
}
}
AbstractBeanDefinitionReader#loadBeanDefinitions(Resource... resources)
@Override
public int loadBeanDefinitions(Resource... resources) throws BeanDefinitionStoreException {
Assert.notNull(resources, "Resource array must not be null");
int counter = 0;
for (Resource resource : resources) {
// 遍歷解析XML文件芹扭,加載 BeanDefinition
counter += loadBeanDefinitions(resource);
}
return counter;
}
接下去的源碼不細(xì)講麻顶,這里載入分為兩大步,
就是通過調(diào)用XML的解析器獲取到 document 對象舱卡,完成通用XML解析辅肾;
-
就是按照Spring的Bean規(guī)則進(jìn)行解析。
Spring的Bean規(guī)則進(jìn)行解析這個過程是BeanDefinitionDocumentReader來實(shí)現(xiàn)的轮锥,里面包含了各種Spring Bean定義規(guī)則的處理矫钓。
這里我覺得核心知識點(diǎn)就是Spring Bean規(guī)則的解析,簡單點(diǎn)來說舍杜,里面包含了我們在XML配置的那些信息新娜,怎么解析成容器中 BeanDefinition的規(guī)則和步驟。這部分由于和主要流程關(guān)系不大既绩。
在這因?yàn)镾pring 的 Bean配置方式有很多概龄,解析配置信息到BeanDefinition的實(shí)現(xiàn)方式也有很多,XML又是現(xiàn)在少用的方式饲握,所以關(guān)于XML中的Spring Bean規(guī)則的解析的詳細(xì)源碼就先略過了私杜。
我們來看下prepareBeanFactory(beanFactory)這個方法
設(shè)置 BeanFactory的類加載器蚕键,添加幾個 BeanPostProcessor,手動注冊幾個特殊的 bean
protected void prepareBeanFactory(ConfigurableListableBeanFactory beanFactory) {
//設(shè)置類加載器衰粹,為當(dāng)前應(yīng)用的application的類加載器
beanFactory.setBeanClassLoader(getClassLoader());
//為bean工廠設(shè)置一個標(biāo)準(zhǔn)的SPEL表達(dá)式解析器
beanFactory.setBeanExpressionResolver(new StandardBeanExpressionResolver(beanFactory.getBeanClassLoader()));
//為bean工廠設(shè)置一個資源編輯器锣光,為了后面bean初始化時,給bean對象賦值
beanFactory.addPropertyEditorRegistrar(new ResourceEditorRegistrar(this, getEnvironment()));
//忽略以下接口的bean寄猩,這些bean都有set方法嫉晶,不會對這些bean進(jìn)行屬性賦值
beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
beanFactory.ignoreDependencyInterface(EnvironmentAware.class);
beanFactory.ignoreDependencyInterface(EmbeddedValueResolverAware.class);
beanFactory.ignoreDependencyInterface(ResourceLoaderAware.class);
beanFactory.ignoreDependencyInterface(ApplicationEventPublisherAware.class);
beanFactory.ignoreDependencyInterface(MessageSourceAware.class);
beanFactory.ignoreDependencyInterface(ApplicationContextAware.class);
//注冊了工廠實(shí)例,如果我們在程序中注入BeanFactory田篇,就是從這里注冊的獲取到的
beanFactory.registerResolvableDependency(BeanFactory.class, beanFactory);
beanFactory.registerResolvableDependency(ResourceLoader.class, this);
beanFactory.registerResolvableDependency(ApplicationEventPublisher.class, this);
beanFactory.registerResolvableDependency(ApplicationContext.class, this);
//注冊事件監(jiān)聽器的bean后置處理接口
beanFactory.addBeanPostProcessor(new ApplicationListenerDetector(this));
//處理AOP的后置處理器
if (beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
//注冊bean工廠的環(huán)境屬性
if (!beanFactory.containsLocalBean(ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(ENVIRONMENT_BEAN_NAME, getEnvironment());
}
if (!beanFactory.containsLocalBean(SYSTEM_PROPERTIES_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_PROPERTIES_BEAN_NAME, getEnvironment().getSystemProperties());
}
if (!beanFactory.containsLocalBean(SYSTEM_ENVIRONMENT_BEAN_NAME)) {
beanFactory.registerSingleton(SYSTEM_ENVIRONMENT_BEAN_NAME, getEnvironment().getSystemEnvironment());
}
}
接下來分析postProcessBeanFactory(beanFactory);
-
這里需要知道BeanFactoryPostProcessor 這個知識點(diǎn)替废,Bean 如果實(shí)現(xiàn)了此接口, 那么在容器初始化以后泊柬,Spring 會負(fù)責(zé)調(diào)用里面的 postProcessBeanFactory 方法椎镣。
提供給子類的擴(kuò)展點(diǎn),到這里的時候兽赁,所有的Bean都加載状答、注冊完成了,但是都還沒有初始化刀崖。
具體的子類可以在這步的時候添加一些特殊的 BeanFactoryPostProcessor 的實(shí)現(xiàn)類或做點(diǎn)什么事惊科。
該方法沒有做實(shí)際的事情,主要是把ServletContextAwareProcessor后置處理器亮钦,給注冊進(jìn)去馆截。
實(shí)現(xiàn)ServletContextAware接口獲取上下文容器,就是從這里注入的蜂莉。
protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
if (this.servletContext != null) {
beanFactory.addBeanPostProcessor(new ServletContextAwareProcessor(this.servletContext));
beanFactory.ignoreDependencyInterface(ServletContextAware.class);
}
WebApplicationContextUtils.registerWebApplicationScopes(beanFactory, this.servletContext);
WebApplicationContextUtils.registerEnvironmentBeans(beanFactory, this.servletContext);
}
接下來分析invokeBeanFactoryPostProcessors(beanFactory);
調(diào)用BeanFactoryPostProcessor實(shí)現(xiàn)類 postProcessBeanFactory(factory) 方法
protected void invokeBeanFactoryPostProcessors(ConfigurableListableBeanFactory beanFactory) {
//獲取FactoryPostProcessors蜡娶,Spring內(nèi)置的和自己設(shè)置的,然后供接下來的調(diào)用
PostProcessorRegistrationDelegate.invokeBeanFactoryPostProcessors(beanFactory, getBeanFactoryPostProcessors());
if (beanFactory.getTempClassLoader() == null && beanFactory.containsBean(LOAD_TIME_WEAVER_BEAN_NAME)) {
beanFactory.addBeanPostProcessor(new LoadTimeWeaverAwareProcessor(beanFactory));
beanFactory.setTempClassLoader(new ContextTypeMatchClassLoader(beanFactory.getBeanClassLoader()));
}
}
public static void invokeBeanFactoryPostProcessors(
ConfigurableListableBeanFactory beanFactory, List<BeanFactoryPostProcessor> beanFactoryPostProcessors) {
//放入已經(jīng)被處理過的bean
Set<String> processedBeans = new HashSet<>();
//當(dāng)前bean工廠是否實(shí)現(xiàn)了BeanDefinitionRegistry映穗,如果有的話窖张,則可以注冊bean定義
if (beanFactory instanceof BeanDefinitionRegistry) {
BeanDefinitionRegistry registry = (BeanDefinitionRegistry) beanFactory;
List<BeanFactoryPostProcessor> regularPostProcessors = new ArrayList<>();
List<BeanDefinitionRegistryPostProcessor> registryProcessors = new ArrayList<>();
//循環(huán)我們傳入的bean工廠后置處理器,并加入到處理器集合中
for (BeanFactoryPostProcessor postProcessor : beanFactoryPostProcessors) {
if (postProcessor instanceof BeanDefinitionRegistryPostProcessor) {
BeanDefinitionRegistryPostProcessor registryProcessor =
(BeanDefinitionRegistryPostProcessor) postProcessor;
registryProcessor.postProcessBeanDefinitionRegistry(registry);
registryProcessors.add(registryProcessor);
}
else {
regularPostProcessors.add(postProcessor);
}
}
//保存當(dāng)前實(shí)例化的BeanDefinitionRegistryPostProcessor
List<BeanDefinitionRegistryPostProcessor> currentRegistryProcessors = new ArrayList<>();
//從bean工廠中獲取到繼承了BeanDefinitionRegistryPostProcessor的bean
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//實(shí)例化優(yōu)先級最高的BeanDefinitionRegistryPostProcessor
if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
//實(shí)例化出BeanDefinitionRegistryPostProcessor的類蚁滋,我們正常初始化這里只有ConfigurationClassPostProcessor
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
//對實(shí)例化出來的BeanDefinitionRegistryPostProcessor進(jìn)行排序
sortPostProcessors(currentRegistryProcessors, beanFactory);
//把實(shí)例化出來的BeanDefinitionRegistryPostProcessor添加進(jìn)總的集合中供后面調(diào)用
registryProcessors.addAll(currentRegistryProcessors);
//調(diào)用剛實(shí)例化出來的bean宿接,注冊bean定義
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
//清空調(diào)用后的BeanDefinitionRegistryPostProcessor
currentRegistryProcessors.clear();
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
//實(shí)例化實(shí)現(xiàn)了Ordered接口的BeanDefinitionRegistryPostProcessor
if (!processedBeans.contains(ppName) && beanFactory.isTypeMatch(ppName, Ordered.class)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
//調(diào)用沒有實(shí)現(xiàn)任何優(yōu)先級接口的BeanDefinitionRegistryPostProcessor
boolean reiterate = true;
while (reiterate) {
reiterate = false;
postProcessorNames = beanFactory.getBeanNamesForType(BeanDefinitionRegistryPostProcessor.class, true, false);
for (String ppName : postProcessorNames) {
if (!processedBeans.contains(ppName)) {
currentRegistryProcessors.add(beanFactory.getBean(ppName, BeanDefinitionRegistryPostProcessor.class));
processedBeans.add(ppName);
reiterate = true;
}
}
sortPostProcessors(currentRegistryProcessors, beanFactory);
registryProcessors.addAll(currentRegistryProcessors);
invokeBeanDefinitionRegistryPostProcessors(currentRegistryProcessors, registry);
currentRegistryProcessors.clear();
}
//調(diào)用 BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
//調(diào)用自己實(shí)現(xiàn)的BeanDefinitionRegistryPostProcessor.postProcessBeanFactory方法
invokeBeanFactoryPostProcessors(regularPostProcessors, beanFactory);
}
else {
//沒有實(shí)現(xiàn)BeanDefinitionRegistry接口的bean工廠,直接調(diào)用invokeBeanFactoryPostProcessors
invokeBeanFactoryPostProcessors(beanFactoryPostProcessors, beanFactory);
}
//調(diào)用所有的BeanDefinitionRegistryPostProcessor完畢
//獲取容器中所有的 BeanFactoryPostProcessor
String[] postProcessorNames =
beanFactory.getBeanNamesForType(BeanFactoryPostProcessor.class, true, false);
//執(zhí)行所有BeanFactoryPostProcessor.postProcessBeanFactory方法辕录,按照order接口排序
List<BeanFactoryPostProcessor> priorityOrderedPostProcessors = new ArrayList<>();
List<String> orderedPostProcessorNames = new ArrayList<>();
List<String> nonOrderedPostProcessorNames = new ArrayList<>();
for (String ppName : postProcessorNames) {
if (processedBeans.contains(ppName)) {
}
else if (beanFactory.isTypeMatch(ppName, PriorityOrdered.class)) {
priorityOrderedPostProcessors.add(beanFactory.getBean(ppName, BeanFactoryPostProcessor.class));
}
else if (beanFactory.isTypeMatch(ppName, Ordered.class)) {
orderedPostProcessorNames.add(ppName);
}
else {
nonOrderedPostProcessorNames.add(ppName);
}
}
sortPostProcessors(priorityOrderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(priorityOrderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> orderedPostProcessors = new ArrayList<>(orderedPostProcessorNames.size());
for (String postProcessorName : orderedPostProcessorNames) {
orderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
sortPostProcessors(orderedPostProcessors, beanFactory);
invokeBeanFactoryPostProcessors(orderedPostProcessors, beanFactory);
List<BeanFactoryPostProcessor> nonOrderedPostProcessors = new ArrayList<>(nonOrderedPostProcessorNames.size());
for (String postProcessorName : nonOrderedPostProcessorNames) {
nonOrderedPostProcessors.add(beanFactory.getBean(postProcessorName, BeanFactoryPostProcessor.class));
}
invokeBeanFactoryPostProcessors(nonOrderedPostProcessors, beanFactory);
//執(zhí)行完成所有BeanFactoryPostProcessor.postProcessBeanFactory方法澄阳,清除所有緩存信息
beanFactory.clearMetadataCache();
}
//我們接下來主要是看ConfigurationClassPostProcessor調(diào)用postProcessBeanDefinitionRegistry方法
private static void invokeBeanDefinitionRegistryPostProcessors(
Collection<? extends BeanDefinitionRegistryPostProcessor> postProcessors, BeanDefinitionRegistry registry) {
for (BeanDefinitionRegistryPostProcessor postProcessor : postProcessors) {
postProcessor.postProcessBeanDefinitionRegistry(registry);
}
}
接下來主要針對于,ConfigurationClassParser類進(jìn)行解析操作處理
public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry registry) {
int registryId = System.identityHashCode(registry);
if (this.registriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanDefinitionRegistry already called on this post-processor against " + registry);
}
if (this.factoriesPostProcessed.contains(registryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + registry);
}
this.registriesPostProcessed.add(registryId);
processConfigBeanDefinitions(registry);
}
public void processConfigBeanDefinitions(BeanDefinitionRegistry registry) {
List<BeanDefinitionHolder> configCandidates = new ArrayList<>();
String[] candidateNames = registry.getBeanDefinitionNames();
//循環(huán)最開始初始化的所有bean定義
for (String beanName : candidateNames) {
BeanDefinition beanDef = registry.getBeanDefinition(beanName);
//對配置類(帶有@Configuration標(biāo)簽)進(jìn)行標(biāo)記踏拜,后續(xù)實(shí)例化時有用
if (beanDef.getAttribute(ConfigurationClassUtils.CONFIGURATION_CLASS_ATTRIBUTE) != null) {
if (logger.isDebugEnable()) {
logger.debug("Bean definition has already been processed as a configuration class: " + beanDef);
}
}
//進(jìn)行標(biāo)記,添加到配置類低剔,候選集合中
else if (ConfigurationClassUtils.checkConfigurationClassCandidate(beanDef, this.metadataReaderFactory)) {
configCandidates.add(new BeanDefinitionHolder(beanDef, beanName));
}
}
if (configCandidates.isEmpty()) {
return;
}
//對所有配置類進(jìn)行排序
configCandidates.sort((bd1, bd2) -> {
int i1 = ConfigurationClassUtils.getOrder(bd1.getBeanDefinition());
int i2 = ConfigurationClassUtils.getOrder(bd2.getBeanDefinition());
return Integer.compare(i1, i2);
});
// 創(chuàng)建我們通過@ComponentScan導(dǎo)入進(jìn)來的bean name的生成器
// 創(chuàng)建我們通過@Import導(dǎo)入進(jìn)來的bean的名稱
SingletonBeanRegistry sbr = null;
if (registry instanceof SingletonBeanRegistry) {
sbr = (SingletonBeanRegistry) registry;
if (!this.localBeanNameGeneratorSet) {
BeanNameGenerator generator = (BeanNameGenerator) sbr.getSingleton(
AnnotationConfigUtils.CONFIGURATION_BEAN_NAME_GENERATOR);
if (generator != null) {
this.componentScanBeanNameGenerator = generator;
this.importBeanNameGenerator = generator;
}
}
}
if (this.environment == null) {
this.environment = new StandardEnvironment();
}
//創(chuàng)建一個類解析器
ConfigurationClassParser parser = new ConfigurationClassParser(
this.metadataReaderFactory, this.problemReporter, this.environment,
this.resourceLoader, this.componentScanBeanNameGenerator, registry);
Set<BeanDefinitionHolder> candidates = new LinkedHashSet<>(configCandidates);
Set<ConfigurationClass> alreadyParsed = new HashSet<>(configCandidates.size());
do {
/**解析配置類速梗,包括@Component肮塞、@ComponentScans等需要掃描的類,都會被解析出來放入bean定義容器
*@Configuration配置類為full配置類姻锁,其他的為lite配置類
**/
parser.parse(candidates);
parser.validate();
//獲取到解析出來的配置類
Set<ConfigurationClass> configClasses = new LinkedHashSet<>(parser.getConfigurationClasses());
configClasses.removeAll(alreadyParsed);
if (this.reader == null) {
this.reader = new ConfigurationClassBeanDefinitionReader(
registry, this.sourceExtractor, this.resourceLoader, this.environment,
this.importBeanNameGenerator, parser.getImportRegistry());
}
//把所有@Import枕赵、@Bean解析出來的bean定義放入容器
this.reader.loadBeanDefinitions(configClasses);
alreadyParsed.addAll(configClasses);
candidates.clear();
if (registry.getBeanDefinitionCount() > candidateNames.length) {
String[] newCandidateNames = registry.getBeanDefinitionNames();
Set<String> oldCandidateNames = new HashSet<>(Arrays.asList(candidateNames));
Set<String> alreadyParsedClasses = new HashSet<>();
for (ConfigurationClass configurationClass : alreadyParsed) {
alreadyParsedClasses.add(configurationClass.getMetadata().getClassName());
}
for (String candidateName : newCandidateNames) {
if (!oldCandidateNames.contains(candidateName)) {
BeanDefinition bd = registry.getBeanDefinition(candidateName);
if (ConfigurationClassUtils.checkConfigurationClassCandidate(bd, this.metadataReaderFactory) &&
!alreadyParsedClasses.contains(bd.getBeanClassName())) {
candidates.add(new BeanDefinitionHolder(bd, candidateName));
}
}
}
candidateNames = newCandidateNames;
}
}
while (!candidates.isEmpty());
if (sbr != null && !sbr.containsSingleton(IMPORT_REGISTRY_BEAN_NAME)) {
sbr.registerSingleton(IMPORT_REGISTRY_BEAN_NAME, parser.getImportRegistry());
}
if (this.metadataReaderFactory instanceof CachingMetadataReaderFactory) {
((CachingMetadataReaderFactory) this.metadataReaderFactory).clearCache();
}
}
//我們再來看看ConfigurationClassPostProcessor.invokeBeanFactoryPostProcessors(registryProcessors, beanFactory);
public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
int factoryId = System.identityHashCode(beanFactory);
if (this.factoriesPostProcessed.contains(factoryId)) {
throw new IllegalStateException(
"postProcessBeanFactory already called on this post-processor against " + beanFactory);
}
this.factoriesPostProcessed.add(factoryId);
if (!this.registriesPostProcessed.contains(factoryId)) {
processConfigBeanDefinitions((BeanDefinitionRegistry) beanFactory);
}
//這里會修改@Configuration配置類的bean定義,到時候?qū)嵗痓ean時位隶,會使用CGLIB創(chuàng)建動態(tài)代理拷窜,@Bean中調(diào)用獲取的bean都是容器中的bean,其他配置類的bean涧黄,獲取的都是new出來的
enhanceConfigurationClasses(beanFactory);
beanFactory.addBeanPostProcessor(new ImportAwareBeanPostProcessor(beanFactory));
}
講了bean定義的加載過程篮昧,現(xiàn)在我們來講一下bean的實(shí)例化過程,bean的實(shí)例化笋妥,主要是finishBeanFactoryInitialization(beanFactory);這個方法
protected void finishBeanFactoryInitialization(ConfigurableListableBeanFactory beanFactory) {
//bean工廠創(chuàng)建轉(zhuǎn)化器
if (beanFactory.containsBean(CONVERSION_SERVICE_BEAN_NAME) &&
beanFactory.isTypeMatch(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class)) {
beanFactory.setConversionService(
beanFactory.getBean(CONVERSION_SERVICE_BEAN_NAME, ConversionService.class));
}
if (!beanFactory.hasEmbeddedValueResolver()) {
beanFactory.addEmbeddedValueResolver(strVal -> getEnvironment().resolvePlaceholders(strVal));
}
//實(shí)例化AOP相關(guān)的組件
String[] weaverAwareNames = beanFactory.getBeanNamesForType(LoadTimeWeaverAware.class, false, false);
for (String weaverAwareName : weaverAwareNames) {
//調(diào)用工廠實(shí)例化方法懊昨,這個方法我們后面來分析
getBean(weaverAwareName);
}
beanFactory.setTempClassLoader(null);
//凍結(jié)所有bean定義,在實(shí)例化時春宣,不允許再修改bean定義
beanFactory.freezeConfiguration();
//實(shí)例化所有bean
beanFactory.preInstantiateSingletons();
}
Spring IOC容器bean的實(shí)例化酵颁,到這基本就完成了,這次所有源代碼的分析把重要的地方月帝,大致流程都講了一遍躏惋,但是有很多細(xì)節(jié)沒有講到,整體屬于框架總體深入流程原理介紹嚷辅。