天天看點

Spring源碼系列02——IOC容器加載過程容器初始化前的一些準備工作IOC容器加載Bean的主要流程

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
        this();
        //将配置類注冊到容器中
        this.register(annotatedClasses);
        //初始化容器
        this.refresh();
    }
           

(1)去擷取一個beanfactory

(2)擷取一個BeanDefinitionReader——一些創世紀的類,實作beanfactorypostProccer接口;

(3)定義一個掃描器:不是解析執行個體的掃描器,是給提供給使用者調用的

doscanner:掃描配置類

org.springframework.context.annotation.AnnotationConfigApplicationContext#register

把使用者的config類注冊到BeanDefinitionMap中;

容器初始化前的一些準備工作

Spring源碼系列02——IOC容器加載過程容器初始化前的一些準備工作IOC容器加載Bean的主要流程

向BeanDefinitionHolder中注冊了如下Processor:

1、internalConfigurationAnnotationProcessor

負責解析處理所有@Configuration标簽類,并将Bean定義注冊到BeanFactory中

Spring如何加載和解析@Configuration标簽

2、internalAutowiredAnnotationProcessor

負責解析@Autowired注解

3、internalRequiredAnnotationProcessor

4、internalCommonAnnotationProcessor

5、internalPersistenceAnnotationProcessor

org.springframework.context.support.AbstractApplicationContext#refresh

public void refresh() throws BeansException, IllegalStateException {

synchronized(this.startupShutdownMonitor) {

this.prepareRefresh();

ConfigurableListableBeanFactory beanFactory = this.obtainFreshBeanFactory();

this.prepareBeanFactory(beanFactory);

try {
            this.postProcessBeanFactory(beanFactory);
            //調用我們的bean工廠的後置處理器,會先執行個體話創世紀的BeanDefinition; //1、會将class轉換成BeanDefinition;2把配置類中的類掃描到BeanDefinitionMap中;
            this.invokeBeanFactoryPostProcessors(beanFactory);
            //注冊bean的後置處理器
            this.registerBeanPostProcessors(beanFactory);
            this.initMessageSource();
            this.initApplicationEventMulticaster();
            this.onRefresh();
            this.registerListeners();
            //注冊所有的單例bean
            this.finishBeanFactoryInitialization(beanFactory);
            this.finishRefresh();
        } catch (BeansException var5) {
            this.logger.warn("Exception encountered during context initialization - cancelling refresh attempt", var5);
            this.destroyBeans();
            this.cancelRefresh(var5);
            throw var5;
        }

    }
}
           

IOC容器加載Bean的主要流程

Spring源碼系列02——IOC容器加載過程容器初始化前的一些準備工作IOC容器加載Bean的主要流程

this.isFactoryBean(beanName)?是不是工廠bean;

factorybean和beanfactory的差別:

factorybean用來修飾普通bean;最終getBean是調用getObject擷取的執行個體;內建mybatis;

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#createBean(java.lang.String, org.springframework.beans.factory.support.RootBeanDefinition, java.lang.Object[])

//第一次調用bean的後置處理器;可以阻止bean的建立;總共有九次調用
beanInstance = this.resolveBeforeInstantiation(beanName, mbd);  

======
//執行個體化bean,此時屬性為空
instanceWrapper = this.createBeanInstance(beanName, mbd, args);

//屬性填充
this.populateBean(beanName, mbd, instanceWrapper);

//初始化; Aware 、@PostConstruct和initLinizing、initMethod
exposedObject = this.initializeBean(beanName, exposedObject, mbd);

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#initializeBean(java.lang.String, java.lang.Object, org.springframework.beans.factory.support.RootBeanDefinition)
//執行AOP動态代理
wrappedBean = this.applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);
加入到一級緩存中
           

問題:

介紹BeanFactoryPostProcesser在spring中的用途?

可以解析配置類

spring中有哪些擴充點,以及調用時機?

在invokeBeanFactoryPostProcessors中會調用BeanFactory後置處理器,解析配置類為beandefinition;

在建立Bean的時候會調用bean的後置處理器;

在屬性填充之後,會調用三個aware回調,beanInitializing,@PostConstruct,@initMethod四個回調。