SpringIOC源码总结

大致的加载过程:

spring ioc容器的加载,大体上经过以下几个过程: 资源文件定位、解析、注册、实例化

1.资源文件定位:主要发生在ApplicationContext中,由于applicationContext继承于ResourceLoader,所以调用getResource()方法,将外部的资源解析成Resource类

2.解析:主要发生在BeanDefinitionReader中完成,最常用的类是XMLBeanDefiniationReader,

ac利用loadBeanDefininiation()方法,负责读取Resource;将Resource的解析交给XMLbeanDefiniationReader去处理,

将XML文档解析成w3c的Document文档,BeanDefinitionDocumentReader进一步解析,BeanDefinitionDocumentReader将Document,交给BeanDefiniationParserDetegate去处理(装饰),如果是标准的NameSpace文档(import、alias、bean、beans),在内部解析,如果不是标准的文档,会委托合适的NameSpaceHander去处理进行解析,将结果封装到BeanDefiniationHolder,最后调用一个工具类来完成对BeanDefinintion的注册

3.注册

Bean的注册是在BeanFactory中完成的,BeanFactory最常用的一个实现类是DefaultListableBeanFactory,它实现了BeanDefinitionRegistry接口,调用了registerBeanDefinition()方法,从而对BeanDefinition进行注册.

所谓的注册就是将BeanDefinition的name和实例保存到一个CurrentHashMap中,最常用的实现DefaultListableBeanFactory,其中的字段就是beanDefinitionMap,是一个ConcurrentHashMap

4.实例化:

注册也完成之后,在BeanFactory的getBean()方法之中,会完成初始化

SpringIOC源码总结

SpringIOC源码总结

容器初始化的核心

Refresh()方法

 

            //1.刷新前的预处理
            // Prepare this context for refreshing.
            prepareRefresh();
            //2.获取beanfactory
            // Tell the subclass to refresh the internal bean factory.
            ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
            //3.beanFactory的预准备工作
            // Prepare the bean factory for use in this context.
            prepareBeanFactory(beanFactory);
​
            try {
                //4.为BeanFactory准备工作完成后,添加一些的后置处理器(用户自定义)
                // Allows post-processing of the bean factory in context subclasses.
                postProcessBeanFactory(beanFactory);
                //5.执行beanFacotry的后置处理器
                // Invoke factory processors registered as beans in the context.
                invokeBeanFactoryPostProcessors(beanFactory);
                //6.注册Bean的后置处理器
                // Register bean processors that intercept bean creation.
                registerBeanPostProcessors(beanFactory);
                //7.初始化消息资源管理(主要用于国际化、消息绑定、消息解析)
                // Initialize message source for this context.
                initMessageSource();
                //8.初始化事件的派发器
                // Initialize event multicaster for this context.
                initApplicationEventMulticaster();
                //9.重新刷新容器,留给子类重写该方法,进行自定义
                // Initialize other special beans in specific context subclasses.
                onRefresh();
                //10.将容器中的ApplicationListener注册进来
                // Check for listener beans and register them.
                registerListeners();
                //11.初始化所有的非懒加载的Bean实例
                // Instantiate all remaining (non-lazy-init) singletons.
                finishBeanFactoryInitialization(beanFactory);
                //12.完成BeanFactory的初始化创建工作
                // Last step: publish corresponding event.
                finishRefresh();
                //IOC容器创建完成

 

 

1.prepareRerfresh()

(1), initPropertySources初始化一些属性设置

(2),getEnvironment().validateRequiredProperties();校验属性和环境的相关设置

(3), this.earlyApplicationEvents = new LinkedHashSet<>();保存容器中的一些早期事件

2.obtainFreshBeanFactory()

(1)refreshBeanFactory();创建BeanFactory对象

    1.如果有BeanFactory,就清空
​
    2.createBeanFactory()创建DefaultListableBeanFactory对象
​
    3.beanFactory.setSerializationId(getId());设置标识符
​
    4.customizeBeanFactory()允许用户自定义一些设置
​
    5.loadBeanDefinitions()解析XML文件并注册成BeanDefinition对象
​
        <1>创建XMLBeanDefinitionReader对象,new XmlBeanDefinitionReader(beanFactory);    
​
        beanFactory其实是BeanDefinitionRegistry对象,因为DefaultListableBeanFactory实现了
​
        BeanDefinitionRegistry接口                                                 
​
        <2>设置并初始化XMLBeanDefinitionReader对象
​
        <3>loadBeanDefinition(beanDefinitionReader)解析XML文件并注册成BeanDefinition对象
​
            的真正方法
​
            其内部:    XmlBeanDefinitionReader无法直接解析配置文件,所以利用了ResourceReader
​
                    将Location配置文件封装成Resource,然后调用重载的方法,先将Resource转换成      
​
                    InputStream在解析成w3c的Doucment对象,最后调用RegisterBeanDefinitions()
​
                        RegisterBeanDefinitions()内部实现:创建一个BeanDefinitionDocumentReader对象                        起到路由的作用
​
                        1.该对象会委托BeanDefinitionParserDelegate()进行真正的解析doc
​
                        调用delegate.parseBeanDefinitionElement(ele),如果是标准的NameSpace文档    
​
                        (import、alias、bean、beans),在内部解析,如果不是标准的文档,会委托合适的
​
                           NameSpaceHander去处理进行解析,将结果封装到BeanDefiniationHolder
​
                        2.调用Delegate对BeanDefinition进行装饰
​
                       3.最后调用工具类方法,进行注册,其实调用的是DefaultListableBeanFactory中的    
​
                          registerBeanDefinition(),该方法主要是beanName放到队列(beanDefinitionNames)                         里,然后把BeanDefinition放到beanDefinitionMap.put(beanName, beanDefinition)                         <concurrentHashMap>

 

(2)getBeanFactory() 获取BeanFactory对象,并返回ConfigurableListableBeanFactory对象

 

3.prepareBeanFactory(beanFactory)

4.postProcessBeanFactory(beanFactory)

5.invokeBeanFactoryPostProcessors( beanFactory)

执行BeanFactoryPostProcessor的方法;  

里有2个接口BeanDefinitionRegistryPostProcessor(BeanFactoryPostProcessors的子类)、BeanFactoryPostProcessors都将会执行它们的后置处理器的方法

1.先执行BeanDefinitionRegistryPostProcessor的方法,(beanDefinition将要被加载在beanfactory中但是还没有实例化,作用是用于自己添加beanDefinition)

     1)、获取所有的BeanDefinitionRegistryPostProcessor;
    2)、看先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor、
        postProcessor.postProcessBeanDefinitionRegistry(registry)
    3)、在执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor;
        postProcessor.postProcessBeanDefinitionRegistry(registry)
    4)、最后执行没有实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessors;
        postProcessor.postProcessBeanDefinitionRegistry(registry)

2.否则的话,BeanFactoryPostProcessor的方法(beanfactory标准初始化之后,来定制beanfactory的内容,所有的beanDefinition已经保存到了beanfactory中但是还没有实例化)

1)、获取所有的BeanFactoryPostProcessor
        2)、看先执行实现了PriorityOrdered优先级接口的BeanFactoryPostProcessor、
            postProcessor.postProcessBeanFactory()
        3)、在执行实现了Ordered顺序接口的BeanFactoryPostProcessor;
            postProcessor.postProcessBeanFactory()
        4)、最后执行没有实现任何优先级或者是顺序接口的BeanFactoryPostProcessor;
            postProcessor.postProcessBeanFactory()

6.RegistryBeanPostProcessor

不同接口类型的BeanPostProcessor,在Bean创建执行前后是不一样的

BeanPostProcessor、 DestructionAwareBeanPostProcessor、 InstantiationAwareBeanPostProcessor、 SmartInstantiationAwareBeanPostProcessor、 MergedBeanDefinitionPostProcessor【internalPostProcessors】、

(1)先获取所有的BeanPostProcessor,这些后置处理器可以通过PriorityOrdered、Ordered接口来执行优先级

(2)先将实现了PriorityOrdered优先级接口的BeanPostProcessor注册到BeanFactory

把每一个BeanPostProcessor注册到BeanFactory中
​
beanFactory.addBeanPostProcessor(postProcessor);

(3)在注册实现了Ordered接口的BeanPostProcessor

(4)最后注册没有实现任何优先级接口的

(5)、最后注册一个ApplicationContextListenerDetector的后置处理器,用于在Bean创建完成后检查是否为ApplicationContextListener,是的话,就会调用ApplicationContext.addApplicationListener((ApplicationListener<?>) bean)将其添加到容器中

7.InitMessageSource

1.获取BeanFactory

2.看容器中是否有id为messageSource的,类型是MessageSource的组件

如果没有就创建一个DelegatingMessageSource,然后把messageSource注入到容器,以后获取国际化的资源可以根据messageSource来获取

8.InitApplcationEventMulticaster

(基于事件派发的组件)

1.获取BeanFactory

2.看容器中是否有id为applicationEventMulticaster的组件

如果没有就创建一个SimpleApplicationEventMulticaster,然后把它注入到容器.

9.onRefresh();

子类重写这个方法,在容器刷新的时候可以自定义逻辑;

10.registerListeners()

1.从容器中获取所有的ApplicationListener

2.将每个监听器添加到事件派发器中; getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);

11.finishBeanFactoryInitialization()

实际上调用的是DefaultListableBeanFactory的preInstantiateSingleton()方法

preInstantiateSingleton()

1.遍历BeanDefinitionMap
​
2.在遍历的时候,调用getMergedLocalBeanDefinition(beanName)将其转换成RootBeanDefinition

注意:普通的Bean在Spring加载Bean定义的时候,实例化出来的是GenericBeanDefinition,而Spring上下文包括实例化所有Bean用的AbstractBeanDefinition是RootBeanDefinition,这时候就使用getMergedLocalBeanDefinition方法做了一次转化,将非RootBeanDefinition转换为RootBeanDefinition以供后续操作

3.在遍历的时候,判断要实例化Bean1.非抽象2.是单例3.非延迟加载

4.在遍历的时候,先判断当前Bean是否为FactoryBean的实现(false,直接调用getBean(beanName))在判断是否为	 

     SmartFactoryBean的实现,假如Bean是SmartFactoryBean的实现并且为eagerInit(渴望加载),也会调用 

     getBean(beanName)立即实例化该Bean

	getBean(beanName)核心doGetBean()为父类AbstractBeanFactory类的doGetBean方法 

	doGetBean()方法

		1.先判断本地的单例缓存中是否缓存过该Bean,如果有缓存就直接从缓存中获取

		2.然后进行一些基本检验,比如检查depend-on属性,用来保证具有依赖关系的Bean先被加载

		3.调用createBean(beanName, mbd, args)用于创建单实例对象
		

		     1.resolveBeforeInstantiation();
						创建bean实例前,让BeanPostProcessor先拦截,是否能返回代理对象;
						也就是给beanPostProcessor一个返回bean的代理对象机会
						内部是【InstantiationAwareBeanPostProcessor】这个拦截器(和AOP有关)
						先触发:postProcessBeforeInstantiation(beanClass, beanName);
						如果有返回值Object bean ,就不会创建bean了在调用                                                       postProcessAfterInitialization(beanClass, beanName)并返回代理bean
						[InstantiationAwareBeanPostProcessor]没有的代理的bean调用doCreateBean()
              
			2.doCreateBean()
                             	AbstractAutowireCapableBeanFactory 的doCreateBean()方法
                    <1>.创建Bean实例,并包装成BeanWrapper    
                        createBeanInstance()方法        
                             判断当前的Bean里面使用的是空参构造还是有参数构造,然后通过反射生成Bean的实							   例。看到前面有一步makeAccessible,这意味着即使Bean的构造函数是private、							   protected的,依然不影响Bean的构造。这里被实例化出来的Bean并不会直接返回,                               而是会被包装为BeanWrapper
                    <2>.允许后置处理器对其进行修改Bean定义 
                        applyMergedBeanDefinitionPostProcessors()    
                             会调用MergedBeanDefinitionPostProcessor的                                                         postProcessMergedBeanDefinition(mbd, beanType, beanName);
                    <3>.属性注入    
                        populateBean()方法       
                            1)、在赋值之前,拿到InstantiationAwareBeanPostProcessor后置处理器
                                调用postProcessAfterInstantiation();    
                            2)、继续拿到InstantiationAwareBeanPostProcessor后置处理器;                               					    调用postProcessPropertyValues();    赋值操作    
                            3)、applyPropertyValues()  真正为属性赋值的方法     
                                    首先进行深拷贝(指的是深度拷贝,遍历PropertyValue然后一个一个赋值到                                     一个新的List,是为了解析Values值中的所有引用),然后在调用                                                 bw.setPropertyValues(new MutablePropertyValues(deepCopy)),遍历                                     deepcopy对象拿到对应的set方法并将方法的可见性设置为true,最后利用反                                   射的机制,对Bean通过反射调用set()方法
                                    (1)拿到写方法并将方法的可见性设置为true

								(2)拿到Value值,对Bean通过反射调用写方法
                      <4>.初始化Bean    
                        initializeBean()方法        
                            1).执行Aware()方法,调用invokeMethodAware(beanName, bean)方法 ,执行								xxxAware接口的方法
                                实现BeanNameAware/BeanClassLoaderAware/BeanFactoryAware.... 才会进行								调用,aware主要是属性赋值后获取其中的信息并且自定义修改       
                            2).执行后置处理器在初始化之前                                                                        applyBeanPostProcessorsBeforeInitialization(wrappedBean,beanName);            
                               BeanPostProcessor.postProcessBeforeInitialization();        
                            3).执行初始化的方法invokeInitMethods(beanName, wrappedBean, mbd)            
                                <1>、是否是InitializingBean接口的实现;执行接口规定的初始化;           
                                <2>、尝试去拿init-method,假如有的话,通过反射,调用initMethod;            
                                因此,两种方法各有优劣:使用实现InitializingBean接口的方式效率更高一点,因为init-method方法是通过反射进行调用的(JVM无法优化在内存中的动态对象);从另外一个角度讲,使用init-method方法之后和Spring的耦合度会更低一点        
                             4).执行后置处理器在初始化之后applyBeanPostProcessorsAfterInitialization           	                       BeanPostProcessor.postProcessAfterInitialization();    
                      		5).注册bean的销毁方法,在容器关闭之前会自动的进行调用    
                             registerDisposableBeanIfNecessary(beanName, bean, mbd);    
                            要注册销毁方法,Bean需要至少满足以下三个条件之一:	
                            (1)Bean是DisposableBean的实现类,此时执行DisposableBean的接口方法									destroy()
                            (2)Bean标签中有配置destroy-method属性,此时执行destroy-method配置指定的							方法
                            (3)当前Bean对应的BeanFactory中持有DestructionAwareBeanPostProcessor接口							的实现类,此时执行 DestructionAwareBeanPostProcessor的接口方法                                       postProcessBeforeDestruction 
	4.创建好Bean后,将其添加到容器中
	5.非单例非原型调用
		bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);(了解)如果bean是	           				 FactoryBean的实现类的话,调用getObject()方法获取真正的对象。

 

流程总结:

[SpringIOC源码总结

12.finishRefresh()

1)、initLifecycleProcessor();初始化和生命周期有关的后置处理器;LifecycleProcessor 默认从容器中找是否有lifecycleProcessor的组件【LifecycleProcessor】;如果没有new

                  DefaultLifecycleProcessor();然后到加入到容器中
写一个LifecycleProcessor的实现类,可以在BeanFactory刷新或者关闭的时候进行调用
				void onRefresh();
				void onClose();

2)、 getLifecycleProcessor().onRefresh();

	拿到前面定义的生命周期处理器(BeanFactory);回调onRefresh();

3)、publishEvent(new ContextRefreshedEvent(this));发布容器刷新完成事件;

发布事件流程:1.获取事件派发器

2.multicastEvent派发事件

3.获取到所有的ApplicaitonListener

4.判断是否需要已异步还是同步的方式进行执行listener的onApplicationEvent()方法