Spring加载bean的原则:

不等bean创建完成就会将创建bean的ObjectFactory提早曝光加入到缓存中。

单例bean在Spring容器里只会创建一次,后续创建时会首先从缓存中获取,尝试加载,不成功则从singletonFatories中加载。当存在循环依赖的时候,依据Spring的加载bean原则,下一个bean需要依赖上一个bean的时候直接使用ObjectFactory。

缓存中保存的是bean的原始状态,需要进行bean的实例化操作。

Spring初始化bean的时候,会首先初始化这个bean所对应的依赖。

package org.springframework.beans.factory;

/**
* Interface to be implemented by objects used within a {@link BeanFactory}
* which are themselves factories. If a bean implements this interface,
* it is used as a factory for an object to expose, not directly as a bean
* instance that will be exposed itself.
*/
public interface FactoryBean<T> { /**
* Return an instance (possibly shared or independent) of the object
* managed by this factory.
*/
T getObject() throws Exception; /**
* Return the type of object that this FactoryBean creates,
* or {@code null} if not known in advance.
*/
Class<?> getObjectType(); /**
* Is the object managed by this factory a singleton? That is,
* will {@link #getObject()} always return the same object
* (a reference that can be cached)?
* 单例对象会放在Spring单例缓存池中
*/
boolean isSingleton(); }

工厂方法配置bean如下:

<bean id="book" class="com.xxx.model.BookFactory"/>

BookFactory实现了FactoryBean,则当使用getBean("book")时,返回FactoryBean#getObject()方法返回的对象,即FactoryBean#getObject()代理了getBean()方法:

Book book = ctx.getBean("book");

如果要获取BookFactoryBean对象,则需要使用前缀“&”,使用如下:

BookFactory bookFactory = ctx.getBean("&book");

单例Bean(singleton)获取步骤: 

singletonObjects<BeanName, BeanInstance>.get(beanName):Map单例缓存获取。synchronized(this.singletonObjects),全局变量同步。

↓↓

↓↓==Null

↓↓

earlySingletonObjects<BeanName, BeanInstance> .get(beanName):处理循环引用依赖检测。

↓↓

↓↓==Null

↓↓

singletonFactories<BeanName, BeanFactory> .get(beanName):调用相应单例创建工厂getObject()返回Bean对象。

↓↓

-->earlySingletonObjects.put(beanName, singletonObject)存储获取的Bean实例。

--> singletonFactories.remove(beanName)移除beanName对应单例工厂。

Bean创建:

  1. if singleton,清除缓存。

  2. 实例化Bean(createBeanInstance),BeanDefinition=》BeanWrapper。

    使用工厂方法创建:RootBeanDefinition存在factoryMethodName,或配置了factory-method=》instantiateUsingFactoryMethod()

    ↓↓

    ↓↓<不存在>

    ↓↓

    根据参数选择相应的构造函数初始化

    ↓↓

    ↓↓<不存在>

    ↓↓

    默认构造函数实例化。

  3. MergeBeanDefinitionPostProcessor:合并后处理,注解处理位置。

  4. 依赖处理。

  5. 属性填充。

  6. 循环依赖检查,Spring处理循环依赖只对singleton有效。

  7. 注册DisposableBean,处理destroy-method。

  8. 完成创建。

Bean初始化:Aware方法,Post处理,Init处理。

  1. Aware:注入相应资源。

  2. PostProcessor:预置处理。

  3. Init处理 :配置init-method或者继承InitializingBean#afterPropertiesSet()方法。afterPropertiesSet先于init-method。

Spring Bean的加载的更多相关文章

  1. Spring Bean 的加载过程

    Spring Bean 的加载过程 一个是populateBean,一个是initializeBean,这两个方法完成了bean的赋值与初始化. 这里有一个BeanDefinitionValueRes ...

  2. Spring Bean 的加载顺序

    一,单一Bean 装载 1. 实例化; 2. 设置属性值; 3. 如果实现了BeanNameAware接口,调用setBeanName设置Bean的ID或者Name; 4. 如果实现BeanFacto ...

  3. spring bean容器加载后执行初始化处理@PostConstruct

    先说业务场景,我在系统启动后想要维护一个List常驻内存,因为我可能经常需要查询它,但它很少更新,而且数据量不大,明显符合缓存的特质,但我又不像引入第三方缓存.现在的问题是,该List的内容是从数据库 ...

  4. BeanDefinitionLoader spring Bean的加载器

    spring 容器注册bean , 会把bean包装成beanDefinition 放进spring容器中,beanDefinitionLoader就是加载bean的类 . 一.源码 class Be ...

  5. Spring Bean配置加载为BeanDefinition全过程(注解配置)

    生产中有很多形式的的配置方式,本文仅分析注解配置.对于其他形式的配置区别主观以为主要在配置文件的解析过程不同,不一一分析了.本文以利用Dubbo框架开发rpc服务端为例详细阐述配置类的解析.数据保存. ...

  6. 【Spring】详解Spring中Bean的加载

    之前写过bean的解析,这篇来讲讲bean的加载,加载要比bean的解析复杂些,该文之前在小编原文中有发表过,要看原文的可以直接点击原文查看,从之前的例子开始,Spring中加载一个bean的方式: ...

  7. Spring源码学习(5)—— bean的加载 part 2

    之前归纳了从spring容器的缓存中直接获取bean的情况,接下来就需要从头开始bean的加载过程了.这里着重看单例的bean的加载 if(ex1.isSingleton()) { sharedIns ...

  8. Spring 源码学习(4)—— bean的加载part 1

    前面随笔中,结束了对配置文件的解析工作,以及将配置文件转换成对应的BeanDefinition存储在容器中.接下来就该进行bean的加载了. public Object getBean(String ...

  9. Spring 系列教程之 bean 的加载

    Spring 系列教程之 bean 的加载 经过前面的分析,我们终于结束了对 XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索.bean 加载的功能实现远比 bean 的 ...

随机推荐

  1. Azure 部署 Asp.NET Core Web App

    在云计算大行其道的时代,当你在部署一个网站时,第一选择肯定是各式各样的云端服务.那么究竟使用什么样的云端服务才能够以最快捷的方式部署一个 ASP.NET Core 的网站呢?Azure 的 Web A ...

  2. Entity Framework 6 Recipes 2nd Edition(11-2)译 -> 用”模型定义”函数过滤实体集

    11-2. 用”模型定义”函数过滤实体集 问题 想要创建一个”模型定义”函数来过滤一个实体集 解决方案 假设我们已有一个客户(Customer)和票据Invoice)模型,如Figure 11-2所示 ...

  3. 使用 Swagger 自动生成 ASP.NET Core Web API 的文档、在线帮助测试文档(ASP.NET Core Web API 自动生成文档)

    对于开发人员来说,构建一个消费应用程序时去了解各种各样的 API 是一个巨大的挑战.在你的 Web API 项目中使用 Swagger 的 .NET Core 封装 Swashbuckle 可以帮助你 ...

  4. GitHub实战系列~3.提交github的时候过滤某些文件 2015-12-10

    GitHub实战系列汇总:http://www.cnblogs.com/dunitian/p/5038719.html ———————————————————————————————————————— ...

  5. 【WCF】基址与默认终结点

    五月份的时候,有位老友给老周提了个建议:希望老周写一写WCF的文章.其实老周以前是写过WCF的文章的,只是不是写在这个博客里,老周并不打算把X年前的博客导进来,要写的话,重新写吧.毕竟,那个时候写的文 ...

  6. Oracle_数据处理

    数据操纵语言 DML(Data Manipulation Language – 数据操纵语言) 可以在下列条件下执行: - 向表中插入数据 - 修改现存数据 - 删除现存数据* 事务是由完成若干项工作 ...

  7. gradlew wrapper使用下载到本地的gradle.zip文件装配--转

    原文地址:http://www.myexception.cn/mobile/1860089.html gradlew wrapper使用下载到本地的gradle.zip文件安装.使用gradlew来b ...

  8. grunt自定义任务——合并压缩css和js

    npm文档:www.npmjs.com grunt基础教程:http://www.gruntjs.net/docs/getting-started/ http://www.w3cplus.com/to ...

  9. Node基础篇(文件操作)

    文件操作 相关模块 Node内核提供了很多与文件操作相关的模块,每个模块都提供了一些最基本的操作API,在NPM中也有社区提供的功能包 fs: 基础的文件操作 API path: 提供和路径相关的操作 ...

  10. .Net Html如何上传图片到一般应用程序

    用html实现图片上传 后台采用.net其中在这里要借用一个js插件 在这里我会写一个图片上传的一个小Demo,有不全的地方多多包容,和提议, 我把已经写好的demo已经上传到百度云 在这里可以下载 ...