一篇文章让你理解 Spring IOC容器创建过程

1. Spring扩展原理

1.1 BeanFactoryPostProcessor

BeanFactory后置处理器,该接口定义了postProcessBeanFactory方法,这个方法在BeanFactory标准初始化之后调用,来定制和修改BeanFactory的内容,所有的bean定义已经保存加载到beanFactory,但是bean的实例还未创建

  • 原理
  1. 容器创建对象,刷新容器 refresh()
  2. 刷新的时候,执行invokeBeanFactoryPostProcessors(beanFactory),这个方法是在finishBeanFactoryInitialization(beanFactory)bean创建之前执行的,所以说BeanFactoryPostProcessor执行是在bean实例创建之前执行的
  3. 直接在BeanFactory中找到所有类型是BeanFactoryPostProcessor的组件,并执行他们的方法

1.2 BeanDefinitionRegistryPostProcessor

这个接口是BeanFactoryPostProcessor的子类,里面定义了postProcessBeanDefinitionRegistry方法,这个方法在所有bean定义信息将要被加载,bean实例还未创建的的时候执行。优先于BeanFactoryPostProcessor执行。利用BeanDefinitionRegistryPostProcessor给容器中再额外添加一些组件。

  • 原理
  1. 容器对象创建
  2. refresh() - > invokeBeanFactoryPostProcessors(beanFactory)
  3. 从容器中获取到所有的BeanDefinitionRegistryPostProcessor组件
    依次触发所有的postProcessBeanDefinitionRegistry()方法
    再来触发postProcessBeanFactory()方法BeanFactoryPostProcessor;
  4. 再来从容器中找到BeanFactoryPostProcessor组件;然后依次触发postProcessBeanFactory()方法

1.3 ApplicationListener

监听容器中发布的事件。
public interface ApplicationListener<E extends ApplicationEvent> 监听ApplicationEvent以及子类

  • 自定义监听器
  1. 创建一个类实现ApplicationListener,实现onApplicationEvent方法,监听某个事件(ApplicationEvent)
  2. 将这个类注册到容器中
  3. 只要容器中有相关事件的发布,就能监听到这个事件,如:
    ContextRefreshedEvent:容器刷新完成(所有bean都完全创建)会发布这个事件;
    ContextClosedEvent:关闭容器会发布这个事件;
  4. 发布一个事件
    applicationContext.publishEvent()
    applicationContext.publishEvent(new ApplicationEvent(new String("自定义event")) { });
  • ContextRefreshedEvent 源码
  1. 容器创建对象 ,刷新容器refresh()
  2. finishRefresh(),publishEvent(new ContextRefreshedEvent(this)),发布ContextRefreshedEvent事件
  • 发布事件流程
  1. 获取事件的多播器(派发器):getApplicationEventMulticaster().multicastEvent(applicationEvent, eventType)
  2. 派发事件,执行multicastEvent:获取所有的applicationListener,如果有executor,可以支持使用Executor进行异步派发,否则,同步的方式直接执行invokeListener(listener, event), 拿到listener回调onApplicationEvent方法。
  • 事件多播器(派发器)
    事件多播器的任务就是调用multicastEvent()方法,通知所有listener,事件发布了,listener执行相应的onApplicationEvent方法。
    事件多播器的获取流程:
  1. 容器创建对象,refresh()刷新
  2. 刷新的时候执行initApplicationEventMulticaster(),初始化事件多播器:
    如果容器中有,就拿出来赋给applicationEventMulticaster
    如果没有,就创建一个SimpleApplicationEventMulticaster,并且加入到容器中,我们就可以在其他组件要派发事件时,自动注入这个applicationEventMulticaster
  • 容器中的监听器

监听器的注册流程:

  1. 容器对象创建,执行refresh()刷新的时候,执行registerListeners方法
  2. registerListeners方法,获取容器中的所有listener,并将listeners注入到多播器中,源码:
//获取所有的listener
String[] listenerBeanNames = getBeanNamesForType(ApplicationListener.class, true, false);
for (String listenerBeanName : listenerBeanNames) {
	//将listener注入到多播器中
	getApplicationEventMulticaster().addApplicationListenerBean(listenerBeanName);
}
  • @EventListener
    指定某个方法监听某个事件,比如指定UserService类中的listen方法监听ApplicationEvent事件
@Component
public class UserService {
    @EventListener(classes=ApplicationEvent.class)//classes为要监听的类型,可以是数组
    public void lisetn(ApplicationEvent event){
        System.out.println("UserService..."+event);
    }
}
  • 原理
    @EventListener 注解,使用EventListenerMethodProcessor处理器来解析方法上的@EventListener,EventListenerMethodProcessor实现了SmartInitializingSingleton接口,这个接口只有一个afterSingletonsInstantiated方法。这个方法会在所有单实例bean已经全部被创建完之后执行。

SmartInitializingSingleton原理:

  1. ioc容器创建对象并refresh();
  2. finishBeanFactoryInitialization(beanFactory),初始化剩下的单实例bean;
    先创建所有的单实例bean,getBean();
    获取所有创建好的单实例bean,判断是否是SmartInitializingSingleton类型的;
    如果是就调用afterSingletonsInstantiated();

2. Spring 容器创建过程

这里主要讲解spring 容器创建过程中的refresh过程。

2.1 prepareRefresh()

  • 刷新前的预处理
  1. initPropertySources():初始化一些属性设置,子类重写这个方法自定义属性
  2. getEnvironment().validateRequiredProperties():检验属性的合法等
  3. this.earlyApplicationEvents = new LinkedHashSet(),保存容器中早期的一些事件

2.2 obtainFreshBeanFactory()

  • 获取BeanFactory
  1. refreshBeanFactory():刷新BeanFactory,设置id,beanFactory是在GenericApplicationContext这个类的无参构造器中创建的
  2. getBeanFactory():获取BeanFactory
  3. 返回BeanFactory【DefaultListableBeanFactory】
public GenericApplicationContext() {
		this.beanFactory = new DefaultListableBeanFactory();
	}

2.3 prepareBeanFactory(beanFactory)

  • BeanFactory的预准备工作(设置BeanFactory中的一些属性)
  1. 设置BeanFactory的类加载器、支持表达式解析器…
  2. 添加部分BeanPostProcessor【ApplicationContextAwareProcessor】
  3. 设置忽略的自动装配的接口EnvironmentAware、EmbeddedValueResolverAware、xxx;
  4. 注册可以解析的自动装配;我们能直接在任何组件中自动注入:
    BeanFactory、ResourceLoader、ApplicationEventPublisher、ApplicationContext
  5. 添加BeanPostProcessor【ApplicationListenerDetector】
  6. 添加编译时的AspectJ;
  7. 给BeanFactory中注册一些能用的组件;
    environment【ConfigurableEnvironment】
    systemProperties【Map<String, Object>】
    systemEnvironment【Map<String, Object>】

2.4 postProcessBeanFactory(beanFactory)

-BeanFactory准备工作完成后进行的后置处理工作

  1. 子类可以重写这个方法,在beanFactory创建及与准备完成后,进行一些后置处理工作

前四步是beanFactory的创建及与准备阶段(标准初始化)。

2.5 invokeBeanFactoryPostProcessors(beanFactory)

  • 执行BeanFactoryPostProcessor的方法
    两个接口:BeanFactoryPostProcessor、BeanDefinitionRegistryPostProcessor

先执行BeanDefinitionRegistryPostProcessor中的postProcessBeanDefinitionRegistry方法

  1. 获取所有的BeanDefinitionRegistryPostProcessor
  2. 先执行实现了PriorityOrdered优先级接口的BeanDefinitionRegistryPostProcessor中的方法
  3. 再执行实现了Ordered顺序接口的BeanDefinitionRegistryPostProcessor中的方法
  4. 最后执行实现任何优先级或者是顺序接口的BeanDefinitionRegistryPostProcessor中的方法
  5. 后执行BeanFactoryPostProcessor中的postProcessBeanFactory(beanFactory)方法,执行过程和BeanDefinitionRegistryPostProcessor 接口一样,都是先执行实现了PriorityOrdered、Ordered接口的BeanFactoryPostProcessor中的方法。

2.6 registerBeanPostProcessors(beanFactory)

  • 注册BeanPostProcessor(Bean的后置处理器)

不同接口类型的BeanPostProcessor;在Bean创建前后的执行时机是不一样的
BeanPostProcessor接口
DestructionAwareBeanPostProcessor、
InstantiationAwareBeanPostProcessor、
SmartInstantiationAwareBeanPostProcessor、
MergedBeanDefinitionPostProcessor【internalPostProcessors】

  1. 获取所有的 BeanPostProcessor。后置处理器都默认可以通过PriorityOrdered、Ordered接口来执行优先级
  2. 先注册PriorityOrdered优先级接口的BeanPostProcesso,把每一个BeanPostProcessor都添加到BeanFactory中
    beanFactory.addBeanPostProcessor(postProcessor);
  3. 再注册Ordered接口的
  4. 最后注册没有实现任何优先级接口的
  5. 之后注册MergedBeanDefinitionPostProcessor;
  6. 最后注册一个ApplicationListenerDetector;来在Bean创建完成后检查是否是ApplicationListener,如果是
    applicationContext.addApplicationListener((ApplicationListener<?>) bean),注册到容器中

2.7 initMessageSource()

  • 初始化MessageSource组件(做国际化功能;消息绑定,消息解析)
  1. 先获取 BeanFactory
  2. 判断BeanFactory中是否有id为messageSource这个组件,有的话就赋给messageSource,没有,就创建一个DelegatingMessageSource,并且在容器中注册,方便其他地方使用。

MessageSource:取出国际化配置文件中的某个key的值;能按照区域信息获取

2.8 initApplicationEventMulticaster()

  • 初始化事件多播器
  1. 先获取beanFactory
  2. 判断beanFactory中是否有applicationEventMulticaster,如果有的话,取出赋给applicationEventMulticaster,没有,就创建一个
    SimpleApplicationEventMulticaster,并且在容器中注册,方便在其他地方使用

2.9 onRefresh()

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

2.10 registerListeners()

  • 注册监听器
  1. 获取所有的ApplicationListener
  2. 将这些ApplicationListener添加到事件派发器中
  3. 判断之前步骤产生的事件earlyApplicationEvents是否为空,如果不为空,就派发

2.11 finishBeanFactoryInitialization(beanFactory)

初始化所有剩下的单实例bean

  1. 主要看preInstantiateSingletons()方法,这个方法初始化剩下的bean
  1. 获取容器中的所有Bean
  2. 获取Bean的定义信息;RootBeanDefinition
  3. 判断,如果bean不是抽象的,是单例的,不是懒加载的
    判断是否是实现FactoryBean接口的Bean;
    不是工厂Bean。利用getBean(beanName)创建对象,这个getBean和ApplicationContext.getBean是同一个方法
  1. getBean过程
  1. doGetBean(name, null, null, false)
  2. getSingleton(beanName)先获取缓存中保存的单实例Bean。如果能获取到说明这个Bean之前被创建过(所有创建过的单实例Bean都会被缓存起来)从private final Map<String, Object> singletonObjects = new ConcurrentHashMap<String, Object>(256) 获取
  3. 缓存中获取不到,开始Bean的创建对象流程;
  4. 标记当前bean已经被创建,markBeanAsCreated(String beanName)
  5. 获取Bean的定义信息,getMergedLocalBeanDefinition(beanName)
  6. 获取当前Bean依赖的其他Bean(相当于xml中标签中的depends-on属性),如果有按照getBean()把依赖的Bean先创建出来;
  7. 启动单实例Bean的创建流程,这里是调用getSingleton(String beanName, ObjectFactory<?> singletonFactory)方法,里面新建了一个beanFactory,并且实现了getObject方法,是通过createBean创建的bean
getSingleton(beanName, new ObjectFactory<Object>() {
						@Override
						public Object getObject() throws BeansException {
							try {
								return createBean(beanName, mbd, args);
							}
							。。。
						}
					});
  1. createBean(beanName, mbd, args)
  1. Object bean = resolveBeforeInstantiation(beanName, mbdToUse),让BeanPostProcessor先拦截返回代理对象‘
  2. 提前执行实现了InstantiationAwareBeanPostProcessor接口的类的方法
    先执行:postProcessBeforeInstantiation(),bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName)
    如果有返回值:触发postProcessAfterInitialization();
  3. 如果前面的InstantiationAwareBeanPostProcessor没有返回代理对象;调用4
  4. doCreateBean(beanName, mbdToUse, args),创建Bean
  1. doCreateBean
  1. 创建Bean实例,createBeanInstance(beanName, mbd, args)
    利用工厂方法或者对象的构造器创建出Bean实例
  2. applyMergedBeanDefinitionPostProcessors(mbd, beanType, beanName),调用MergedBeanDefinitionPostProcessor的postProcessMergedBeanDefinition(mbd, beanType, beanName)方法
  3. Bean属性赋值populateBean(beanName, mbd, instanceWrapper)
    赋值之前
    拿到InstantiationAwareBeanPostProcessor后置处理器,执行postProcessAfterInstantiation方法
    拿到InstantiationAwareBeanPostProcessor后置处理器,执行postProcessPropertyValues方法
    赋值:applyPropertyValues(beanName, mbd, bw, pvs),应用Bean属性的值;为属性利用setter方法等进行赋值;
  1. bean 创建好并赋值后,就进行初始化initializeBean
  1. 执行Aware接口方法,invokeAwareMethods(beanName, bean),有BeanNameAware\BeanClassLoaderAware\BeanFactoryAware
  2. 执行后置处理器初始化之前的方法,applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
    BeanPostProcessor.postProcessBeforeInitialization()
  3. 执行初始化方法,invokeInitMethods(beanName, wrappedBean, mbd)
    是否是InitializingBean接口的实现;执行接口规定的初始化方法;
    是否自定义初始化方法;
  4. 执行后置处理器初始化之后的方法,applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName)
    BeanPostProcessor.postProcessAfterInitialization()

bean 初始化完成之后,registerDisposableBeanIfNecessary(beanName, bean, mbd),注册bean的销毁方法

到这里,bean就创建完成了。
创建完成之后,将创建的Bean添加到缓存中singletonObjects,addSingleton(beanName, singletonObject)

IOC容器就是很多的Map,里面保存了bean的信息、环境信息等各种各样的信息

所有Bean都利用getBean创建完成以后,检查所有的Bean是否是SmartInitializingSingleton接口的,如果是,就执afterSingletonsInstantiated()。

2.12 finishRefresh()

  • 完成beanFactory的创建工作
  1. initLifecycleProcessor(),初始化和生命周期有关的处理器,LifecycleProcessor
    默认从容器中找是否有LifecycleProcessor的组件【LifecycleProcessor】,如果没有就新建一个DefaultLifecycleProcessor,并加入到容器中
    可以写一个类实现LifecycleProcessor接口,重写onRefresh()、onClose()方法,在beanFactory刷新完成或者close后回调相关方法
  2. getLifecycleProcessor().onRefresh(),拿到前面定义的生命周期处理器(BeanFactory),回调onRefresh()
  3. publishEvent(new ContextRefreshedEvent(this)),发布容器刷新完成事件
  4. LiveBeansView.registerApplicationContext(this)

至此,容器创建及初始化完成

3. 总结

  1. Spring容器在启动的时候,先会保存所有注册进来的Bean的定义信息;
  • xml注册bean;
  • 注解注册Bean;@Service、@Component、@Bean、xxx
  1. Spring容器会合适的时机创建这些Bean
  • 用到这个bean的时候;利用getBean创建bean;创建好以后保存在容器中;
  • 统一创建剩下所有的bean的时候;finishBeanFactoryInitialization();

3.后置处理器;BeanPostProcessor

每一个bean创建完成,都会使用各种后置处理器进行处理;来增强bean的功能;
AutowiredAnnotationBeanPostProcessor:处理自动注入
AnnotationAwareAspectJAutoProxyCreator:来做AOP功能;
xxx…
增强的功能注解:
AsyncAnnotationBeanPostProcessor

  1. 事件驱动模型;

ApplicationListener;事件监听;
ApplicationEventMulticaster;事件派发:

参考:
Spring注解驱动教程

猜你喜欢

转载自blog.csdn.net/weixin_43691723/article/details/106662070