0. 通常,无论是DispatcherServlet、ContextLoaderListener还是ClassPathXmlApplicationContext,首次实例化bean的入口并不是在每次调用getBean的时候,而是在DefaultListableBeanFactory类的preInstantiateSingletons方法中:当配置文件加载完毕后,会预先将 非abstract、非延迟加载(lazy-init=false)的单例类 通过AbstractBeanFactory的getBean方法初始化到Spring容器中备用
1. 无论是哪个getBean方法的重载,终于都会归结到doGetBean方法的调用
2. 首先,doGetBean方法会将传入的String型的name参数格式化成Spring容器所采用的beanName,格式化主要有两点:一是将Spring框架类(如各种BeanFactory等)自带的前缀去掉,二是将使用了别名(alias)的bean的别名转换成真名
3. bean在Spring中的单例定义对象(sharedInstance)在Spring容器中是存放在一个名叫singletonObjects的ConcurrentHashMap中,根据格式化后的beanName去获取sharedInstance(这一过程中可能该sharedInstance正在创建中,此种情况下将返回该sharedInstance的一个早期引用)
4. 判断sharedInstance是否存在:
4.1. 若sharedInstance存在,则直接利用它来调用getObjectForBeanInstance
4.2.1. 若不存在,则从尝试从父BeanFactory中获取bean
4.2.2. 若从父BeanFactory中获取失败,则先通过beanName获取到bean的定义对象mbd,然后优先实例化从mbd中获取到的该bean所依赖的其它bean
4.2.2.1. 若mbd中定义该bean为singleton,则创建该bean的sharedInstance(真正创建sharedInstance的过程实际是调用ObjectFactory接口的createBean方法,由AbstractAutowireCapableBeanFactory类实现)
4.2.2.2. 若定义为prototype,则创建一个scopedInstance替代sharedInstance
4.2.3. 创建完成后也是调用getObjectForBeanInstance进入下一步
5.1. getObjectForBeanInstance方法首先判断传入的beanInstance(sharedInstance或scopedInstance)是否是一个工厂类的间接引用但同时它又不是一个工厂类(true则抛异常)
5.2. 若不是工厂类,或者是工厂类的一个间接引用,则直接返回该beanInstance
5.3. 若beanInstance是工厂类,则通过该工厂类生成真正的实例,并返回
6. 若最早传入的参数中有指定Class<?>,则进行类型强制转换,否则直接返回实例