Spring Bean的加载
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创建:
if singleton,清除缓存。
实例化Bean(createBeanInstance),BeanDefinition=》BeanWrapper。
使用工厂方法创建:RootBeanDefinition存在factoryMethodName,或配置了factory-method=》instantiateUsingFactoryMethod()
↓↓
↓↓<不存在>
↓↓
根据参数选择相应的构造函数初始化
↓↓
↓↓<不存在>
↓↓
默认构造函数实例化。
MergeBeanDefinitionPostProcessor:合并后处理,注解处理位置。
依赖处理。
属性填充。
循环依赖检查,Spring处理循环依赖只对singleton有效。
注册DisposableBean,处理destroy-method。
完成创建。
Bean初始化:Aware方法,Post处理,Init处理。
Aware:注入相应资源。
PostProcessor:预置处理。
Init处理 :配置init-method或者继承InitializingBean#afterPropertiesSet()方法。afterPropertiesSet先于init-method。
Spring Bean的加载的更多相关文章
- Spring Bean 的加载过程
Spring Bean 的加载过程 一个是populateBean,一个是initializeBean,这两个方法完成了bean的赋值与初始化. 这里有一个BeanDefinitionValueRes ...
- Spring Bean 的加载顺序
一,单一Bean 装载 1. 实例化; 2. 设置属性值; 3. 如果实现了BeanNameAware接口,调用setBeanName设置Bean的ID或者Name; 4. 如果实现BeanFacto ...
- spring bean容器加载后执行初始化处理@PostConstruct
先说业务场景,我在系统启动后想要维护一个List常驻内存,因为我可能经常需要查询它,但它很少更新,而且数据量不大,明显符合缓存的特质,但我又不像引入第三方缓存.现在的问题是,该List的内容是从数据库 ...
- BeanDefinitionLoader spring Bean的加载器
spring 容器注册bean , 会把bean包装成beanDefinition 放进spring容器中,beanDefinitionLoader就是加载bean的类 . 一.源码 class Be ...
- Spring Bean配置加载为BeanDefinition全过程(注解配置)
生产中有很多形式的的配置方式,本文仅分析注解配置.对于其他形式的配置区别主观以为主要在配置文件的解析过程不同,不一一分析了.本文以利用Dubbo框架开发rpc服务端为例详细阐述配置类的解析.数据保存. ...
- 【Spring】详解Spring中Bean的加载
之前写过bean的解析,这篇来讲讲bean的加载,加载要比bean的解析复杂些,该文之前在小编原文中有发表过,要看原文的可以直接点击原文查看,从之前的例子开始,Spring中加载一个bean的方式: ...
- Spring源码学习(5)—— bean的加载 part 2
之前归纳了从spring容器的缓存中直接获取bean的情况,接下来就需要从头开始bean的加载过程了.这里着重看单例的bean的加载 if(ex1.isSingleton()) { sharedIns ...
- Spring 源码学习(4)—— bean的加载part 1
前面随笔中,结束了对配置文件的解析工作,以及将配置文件转换成对应的BeanDefinition存储在容器中.接下来就该进行bean的加载了. public Object getBean(String ...
- Spring 系列教程之 bean 的加载
Spring 系列教程之 bean 的加载 经过前面的分析,我们终于结束了对 XML 配置文件的解析,接下来将会面临更大的挑战,就是对 bean 加载的探索.bean 加载的功能实现远比 bean 的 ...
随机推荐
- ADO.NET Entity Framework 在哪些场景下使用?
在知乎回答了下,顺手转回来. Enity Framework已经是.NET下最主要的ORM了.而ORM从一个Mapping的概念开始,到现在已经得到了一定的升华,特别是EF等对ORM框架面向对象能力的 ...
- 微信小程序首次官方分享的纪要
先交代备注: 这次有关小程序的分享只有技术的 QA环节,其他如产品.入口.流量.与公众号的整合等等,回答都是暂时无法给出答案或不确定: 小程序最终发布时间官方也还未确定,不过说应该就是近期: 小程序的 ...
- Entity Framework 6 Recipes 2nd Edition(12-5)译 -> 自动删除相关联实体
12-5. 自动删除相关联实体 问题 当一个实体被删除时,你想自动删除它相关联的实体 解决方案 假设你有一个表结构由一个course (科目), course 的classes (课程),以及enro ...
- Android开发之Android Material Design Toolbar自定义随笔
一.自定义Toolbar的menu: 在menu下新建menu.xml文件,自定义menu的样式: <menu xmlns:android="http://schemas.androi ...
- 对jquery操作复选框
摘要:jquery操作复选框.使用更简洁易懂,思路清晰,逻辑更明了,很实用 <!DOCTYPE html> <html> <head> <meta chars ...
- php使用CI发送qq和163邮件
1.需求 发送邮件 2.介绍 使用CI框架的email类库发送邮件,这里演示QQ和163 3.163使用教程 a.先去163邮件开启smtp邮件. b.在CI的控制器里写下面的代码 $this-> ...
- Android笔记——Handler Runnable与Thread的区别
在java中可有两种方式实现多线程,一种是继承Thread类,一种是实现Runnable接口:Thread类是在java.lang包中定义的.一个类只要继承了Thread类同时覆写了本类中的run() ...
- WCF学习之旅—WCF中传统的异常处理(十六)
WCF中的异常处理 在软件开发过程中,不可能没有异常的出现,所以在开发过程中,对不可预知的异常进行解决时,异常处理显得尤为重要.对于一般的.NET系统来说,我们简单地借助try/catch可以很容易地 ...
- 后HTML5时代
十二年前,无论多么复杂的布局,在我们神奇的table面前,都不是问题:十年前,阿捷的一本<网站重构>,为我们开启了新的篇章:八年前,我们研究yahoo.com,惊叹它在IE5下都表现得如此 ...
- ASP.NET Core中的依赖注入(4): 构造函数的选择与服务生命周期管理
ServiceProvider最终提供的服务实例都是根据对应的ServiceDescriptor创建的,对于一个具体的ServiceDescriptor对象来说,如果它的ImplementationI ...