Srping IOC容器创建过程

1.通过注解AnnotationConfigApplicationContext进行启动,启动类如下

@ComponentScan("test")
public class TestApp {

  public static void main(String[] args) {
    AnnotationConfigApplicationContext applicationContext = new AnnotationConfigApplicationContext(TestApp.class);
  }

}

2.AnnotationConfigApplicationContext调用构造函数进行初始化,继承了GenericApplicationContext,而GenericApplicationContext实现了BeanDefinitionRegistry接口,所以注册了传入进来的类。

public AnnotationConfigApplicationContext(Class<?>... annotatedClasses) {
  this();
  register(annotatedClasses);
  refresh();
}

3.调用refresh方法进行创建刷新IOC容器。在AbstractApplicationContext中具体实现。

//准备刷新容器,初始化一些属性
prepareRefresh();
// Tell the subclass to refresh the internal bean factory.告诉子类刷新内部bean工厂
ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();

// Prepare the bean factory for use in this context. 准备在这种情况下使用的bean工厂
//设置上下文回调配置bean工作 beanFactory.addBeanPostProcessor(new ApplicationContextAwareProcessor(this));
//注册默认环境bean
prepareBeanFactory(beanFactory);

//允许在子类中对bean工厂进行后处理。
postProcessBeanFactory(beanFactory);
//调用在上下文中注册为bean的工厂处理器。
invokeBeanFactoryPostProcessors(beanFactory);
//注册拦截Bean创建的Bean处理器。
registerBeanPostProcessors(beanFactory);
//为此上下文初始化消息源。国际化做准备
initMessageSource();
//为此上下文初始化事件多播器。
initApplicationEventMulticaster();
//在特定上下文子类中初始化其他特殊bean。
onRefresh();
//检查侦听器bean并注册它们
registerListeners();

//实例化所有剩余的(非延迟初始化non-lazy-init)单例。
finishBeanFactoryInitialization(beanFactory);

//最后一步:发布相应的事件。
finishRefresh();

4.finishBeanFactoryInitialization方法中,如果没有bean后处理器,则注册默认的嵌入式值解析器EmbeddedValueResolver
//实例化所有剩余的(非延迟初始化)单例。
调用beanFactory.preInstantiateSingletons();在DefaultListableBeanFactory中具体实现。

5.循环遍历所有注册的非抽象的非懒觉加载的单例bean,判断isFactoryBean是否FactoryBean,如果是通过getBean("&" + beanName)获取bean,如果不是直接getBean(beanName);

6.getBean为父类抽象类AbstractBeanFactory方法实现,直接返回调用doGetBean(name, null, null, false);方法。

7.通过getSingleton(beanName);看能否在三级缓存中获取到bean。如果获取不到,getParentBeanFactory();则看是否能在父容器中获取到,获取到则返回。

  spring三级缓存:

    一级缓存singletonObjects          存放初始化后的单例对象,完整的bean对象
    二级缓存earlySingletonObjects  存放实例化,未完成初始化的单例对象(未完成属性注入的对象) getEarlyBeanReference(beanName, mbd, bean)有可能会进行AOP的增强,创建代理类,因此二级缓存earlySingletonObjects存放的有可能是经过AOP增强的代理对像。
    三级缓存singletonFactories    存放ObjectFactory对象,存放的是工厂对象,用来解决Aop问题

8.markBeanAsCreated(beanName);标记bean已被创建。 Bean在创建的时候可以给该Bean打标,如果递归调用回来发现正在创建中的话,即说明了循环依赖了。

9.通过RootBeanDefinition判断是否是单例,如果是单例,则通过getSingleton获取实例。

if (mbd.isSingleton()) {
sharedInstance = getSingleton(beanName, () -> {
try {
return createBean(beanName, mbd, args);
}
catch (BeansException ex) {
// Explicitly remove instance from singleton cache: It might have been put there
// eagerly by the creation process, to allow for circular reference resolution.
// Also remove any beans that received a temporary reference to the bean.
destroySingleton(beanName);
throw ex;
}
});
bean = getObjectForBeanInstance(sharedInstance, name, beanName, mbd);
}

10.getSingleton先对synchronized (this.singletonObjects) 对一级缓存进行加锁,最后通过传入参数的ObjectFactory<?> singletonFactory中的getObject方法进行获取bean,实际为调用createBean(beanName, mbd, args);方法。

11.createBean实际实现在AbstractAutowireCapableBeanFactory抽象类中,

//给BeanPostProcessors一个返回代理而不是目标bean实例的机会
    Object bean = resolveBeforeInstantiation(beanName, mbdToUse);
    如果容量里注册有hasInstantiationAwareBeanPostProcessors,
    //applyBeanPostProcessorsBeforeInstantiation里面循环调用InstantiationAwareBeanPostProcessor的postProcessBeforeInstantiation方法,如果返回的bean不为null,则循环调用BeanPostProcessor的postProcessAfterInitialization方法,
    然后直接返回bean,不会继续往下进行创建bean等。所以postProcessPropertyValues,postProcessAfterInstantiation,postProcessBeforeInitialization等方法都不会再被调用。
    bean = applyBeanPostProcessorsBeforeInstantiation(targetType, beanName);
    if (bean != null) {
        bean = applyBeanPostProcessorsAfterInitialization(bean, beanName);
    }

12.如果上面没有获取到bean,则进入doCreateBean进行创建bean。
Object beanInstance = doCreateBean(beanName, mbdToUse, args);
//通过构造器创建实例,但还没有注入属性,调用初始化方法。
instanceWrapper = createBeanInstance(beanName, mbd, args);

如果是单例并且允许循环引用的话,则创建早期引用ObjectFactory放入三级缓存singletonFactories中。
addSingletonFactory(beanName, () -> getEarlyBeanReference(beanName, mbd, bean));

然后通过populateBean(beanName, mbd, instanceWrapper);为bean注入属性,在此解决循环引用。
先循环调用InstantiationAwareBeanPostProcessor的postProcessAfterInstantiation方法。如果任一后处理器此方法返回false,则退出属性注入方法,不在继续往下执行。
循环调用InstantiationAwareBeanPostProcessor的postProcessProperties,如果返回null继续调用其postProcessPropertyValues方法。
(postProcessProperties和postProcessPropertyValues方法,后者是老版本中的实现,已经废弃,所以直接看postProcessProperties)
然后对属性进行注入。

注入属性后exposedObject = initializeBean(beanName, exposedObject, mbd);对bean进行初始化,
调用invokeAwareMethods(beanName, bean);如果bean实现了感知类BeanNameAware,BeanClassLoaderAware,BeanFactoryAware接口,则按顺序调用接口方法setXXX设置进去。
调用applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);循环调用BeanPostProcessor的postProcessBeforeInitialization方法。
调用invokeInitMethods(beanName, wrappedBean, mbd);进行初始化,先调用InitializingBean的afterPropertiesSet方法,如果bean实现了此接口的话,然后反射调用(原因是无固定具体实现名?)设置的init-method方法。
applyBeanPostProcessorsAfterInitialization(wrappedBean, beanName);循环调用BeanPostProcessor的postProcessAfterInitialization方法,AOP创建代理对象也是在此实现的,通过AnnotationAwareAspectJAutoProxyCreator的父类AbstractAutoProxyCreator的postProcessAfterInitialization 方法。

registerDisposableBeanIfNecessary(beanName, bean, mbd);为bean注册销毁方法,如果有实现DisposableBean接口destory方法,定义destory-method方法的话。

最后通过addSingleton(beanName, singletonObject);放入一级缓存singletonObjects并在其他缓存中移除。

posted @ 2021-03-03 22:11  RunTheNight  阅读(117)  评论(0编辑  收藏  举报