Spring源码分析之lazy-init属性的配置
AbstractApplicationContext类默认在容器初始化的过程中就会执行依赖注入,即等价于配置lazy-init属性为false,bean的配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:context="http://www.springframework.org/schema/context"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd"><bean id="studentService" class="com.verify.constant.StudentService" init-method="initMethod" lazy-init="false"/>
</beans>
容器的初始化是在AbstractApplicationContext的refresh()方法中执行的,如下代码对lazy-init进行了处理:
finishBeanFactoryInitialization(beanFactory);
跟踪下去可以找到真正的读取lazy-init属性进行懒加载相关处理的地方
@Overridepublic void preInstantiateSingletons() throws BeansException {if (this.logger.isDebugEnabled()) {this.logger.debug("Pre-instantiating singletons in " + this);}// Iterate over a copy to allow for init methods which in turn register new bean definitions.// While this may not be part of the regular factory bootstrap, it does otherwise work fine.List<String> beanNames = new ArrayList<String>(this.beanDefinitionNames);// Trigger initialization of all non-lazy singleton beans...for (String beanName : beanNames) {RootBeanDefinition bd = getMergedLocalBeanDefinition(beanName);if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit()) {if (isFactoryBean(beanName)) {final FactoryBean<?> factory = (FactoryBean<?>) getBean(FACTORY_BEAN_PREFIX + beanName);boolean isEagerInit;if (System.getSecurityManager() != null && factory instanceof SmartFactoryBean) {isEagerInit = AccessController.doPrivileged(new PrivilegedAction<Boolean>() {@Overridepublic Boolean run() {return ((SmartFactoryBean<?>) factory).isEagerInit();}}, getAccessControlContext());}else {isEagerInit = (factory instanceof SmartFactoryBean &&((SmartFactoryBean<?>) factory).isEagerInit());}if (isEagerInit) {getBean(beanName);}}else {getBean(beanName);}}}// Trigger post-initialization callback for all applicable beans...for (String beanName : beanNames) {Object singletonInstance = getSingleton(beanName);if (singletonInstance instanceof SmartInitializingSingleton) {final SmartInitializingSingleton smartSingleton = (SmartInitializingSingleton) singletonInstance;if (System.getSecurityManager() != null) {AccessController.doPrivileged(new PrivilegedAction<Object>() {@Overridepublic Object run() {smartSingleton.afterSingletonsInstantiated();return null;}}, getAccessControlContext());}else {smartSingleton.afterSingletonsInstantiated();}}}}
可以看到代码中对所有注册的bean,即this.beanDefinitionNames,对于每个bean都会做如下判断,如果成立就会执行依赖注入:
if (!bd.isAbstract() && bd.isSingleton() && !bd.isLazyInit())
可以看出,只有单例的bean才有可能在容器初始化的时候就完成依赖注入,当lazy-init属性不配置(默认值)或者配置为false的时候,上述if就会成立,当然这里默认不配置abstract属性,所以它默认也是false。if成立,就会执行getBean从而进行依赖注入,这样在容器初始化的过程中就已经实例化了Bean,当真正的请求bean的时候,其实只是从缓存中读取而已。
而如果lazy-init属性配置为true,那么就会进行懒加载了,这样在容器初始化的过程中不会进行依赖注入,只有当第一个getBean的时候才会实例化Bean。
最后抛出一个我还没有搞明白的问题:
书上说的是容器在初始化的过程中默认情况下其实并没有发生依赖注入,而是在第一次getBean的时候才会进行依赖注入,但是这个说法与上述AbstractApplicationContext的容器初始化过程好像是不一致的?还是说AbstractApplicationContext默认是进行依赖注入,但是BeanFactory默认不进行依赖注入?
Spring源码分析之lazy-init属性的配置相关推荐
- 手撸spring源码分析IOC实现原理
手撸spring源码分析IOC实现原理 文章出处:https://github.com/fuzhengwei/small-spring 根据小付哥的手撸spring核心源码一步步学习出来的结果收货总结 ...
- Spring源码分析八:Mybatis ORM映射框架原理
文章目录 (一)Mybatis单独操作数据库程序 1.1.数据库表 1.2.建立PO 1.3.建立mapper接口映射 1.4.建立Mybatis配置文件 1.5.建立mapper映射文件 1.6.测 ...
- Spring源码分析之Bean的创建过程详解
前文传送门: Spring源码分析之预启动流程 Spring源码分析之BeanFactory体系结构 Spring源码分析之BeanFactoryPostProcessor调用过程详解 本文内容: 在 ...
- Spring 源码分析衍生篇十三 :事务扩展机制 TransactionSynchronization
文章目录 一.前言 二.TransactionSynchronization 1. TransactionSynchronization 1.1 TransactionSynchronization ...
- spring源码分析之spring-core总结篇
1.spring-core概览 spring-core是spring框架的基石,它为spring框架提供了基础的支持. spring-core从源码上看,分为6个package,分别是asm,cgli ...
- 【spring源码分析】IOC容器初始化(二)
前言:在[spring源码分析]IOC容器初始化(一)文末中已经提出loadBeanDefinitions(DefaultListableBeanFactory)的重要性,本文将以此为切入点继续分析. ...
- Spring 源码分析(三) —— AOP(五)创建代理
2019独角兽企业重金招聘Python工程师标准>>> 创建代理 代理的定义其实非常简单,就是改变原来目标对象方法调用的运行轨迹.这种改变,首先会对这些方法进行拦截,从而为这些方法提 ...
- spring源码分析之BeanDefinition相关
目录 前言: BeanDefinition的家族系列 1.BeanDefintion的UML类图 2.BeanDefintion家族类详解 2.1.通用接口 2.2.BeanDefintion接口 2 ...
- Spring源码分析(三)
Spring源码分析 第三章 手写Ioc和Aop 文章目录 Spring源码分析 前言 一.模拟业务场景 (一) 功能介绍 (二) 关键功能代码 (三) 问题分析 二.使用ioc和aop重构 (一) ...
- Spring 源码分析 (一)——迈向 Spring 之路
一切都是从 Bean 开始的 在 1996 年,Java 还只是一个新兴的.初出茅庐的编程语言.人们之所以关注她仅仅是因为,可以使用 Java 的 Applet 来开发 Web 应用.但这些开发者很快 ...
最新文章
- 模拟人类医生,自动生成靠谱医学报告,腾讯医典创新方法入选CVPR 2021
- 获取AFP共享的文件夹及其权限
- 英伟达“神笔马良”GauGAN发布Windows应用程序,可导出PSD文件
- Ubuntu常用翻译工具——星际译王StarDict
- 基于InfluxDB+Grafana打造大数据监控利器--转
- 一行Java代码判断文件夹是否存在,不存在则新建
- matplotlib(3)
- 获取IP地址和MAC地址
- java小编程----反转字符串中的每一个单词
- 实战手记:让百万级数据瞬间导入SQL Server
- 项目管理工具project软件学习(六) - 设置里程碑、任务备注
- 前端-requests-flask对应关系 file
- 【DRP】【SQL】-悲观锁-防止多用户同时操作时出现脏数据
- ESXi主机性能问题
- mysql charactersetdatabase_Mysql5.7.22 坑爹的 `character_set_database`
- c语言编程中%d怎么运用的,C语言格式符%d与%D的区别
- Nginx支持ipv6
- 【阿里Java技术进阶】官方钉群直播大全(持续更新)...
- CSS基础--absolute与overflow
- ABAP学习笔记-基础语法-06-流程控制(01)-条件语句