Spring5源码 - 01 BeanDefination源码分析

简介: Spring5源码 - 01 BeanDefination源码分析

20200914143739548.png

引入

Spring 是如何生成一个Bean的?

我们先看个例子


2020091108493851.png


我们有个Configuration类AppConfig ,通过ComponentScan定义了扫描com.artisan目录下所有表了标注了注解的Bean

package com.artisan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
@Configuration
@ComponentScan("com.artisan")
public class AppConfig {
}

同时com.artisan目录下还有A.class 和 B.class , 其中B类上标注了@Component注解,A上仅仅一个普通的Java类

package com.artisan.test;
import org.springframework.stereotype.Component;
@Component
public class B { 
}
package com.artisan.test;
public class A {
}

我们启动下Spring容器,然后尝试去重bean容器中获取A和B的单例对象,看看会发生什么?

package com.artisan.test;
import com.artisan.AppConfig;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
public class BeanLoadTest {
  public static void main(String[] args) {
    // spring容器
    AnnotationConfigApplicationContext ac = new AnnotationConfigApplicationContext(AppConfig.class);
    System.out.println(ac.getBean(B.class));
    System.out.println(ac.getBean(A.class));
  }
}


结果显而易见, 被标注了@Component注解的B类,成功的从bean容器中获取到了,而A类是无法从bean容器中获取到的 ( No qualifying bean of type ‘com.artisan.test.A’ available)。

com.artisan.test.B@28864e92
Exception in thread "main" org.springframework.beans.factory.NoSuchBeanDefinitionException: No qualifying bean of type 'com.artisan.test.A' available
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:351)
  at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBean(DefaultListableBeanFactory.java:342)
  at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1177)
  at com.artisan.test.BeanLoadTest.main(BeanLoadTest.java:12)


这是为什么呢?Spring的源码是如何实现的呢? 接下来的文章,我们逐层揭开Sping Bean的神秘面纱 …


Bean实例化的原理


我们知道普通的Java类的实例化的过程,被JVM编译成字节码文件以后,通过new 关键字实例化。


Spring bean的实例化区别于普通Java类的实例化过程,是一个相对复杂的过程。


原理如下


1. 扫描到可以受到Spring管理的Bean,将其转化成BeanDefinition


2. BeanDefinition是个接口,其中有很多属性可以设置,比如 scope 、lazyInit、dependson 、autoType 、关联的是哪个类setBeanClass 等等


3. 将BeanDefinition放入到一个Map中


4. 遍历Map ,取出BeanDefinition,根据你上一步设置的各种属性,去做不同的操作,比如autoType 、是否懒加载等等等等,实例化Bean


5. 实例化完成以后,将实例化好的Bean放到map中 (就是spring容器),即Spring的单例池 singletonObjectsMap。


这里只会创建单例模式的Bean,prototype等类型的bean不会添加到单例池中,因为prototype每次都会new一个,没有必要去缓存。


当然了,Spring的实现是很复杂的,我们这里先对其大致的过程和原理有个初步的了解,方便后续源码的展开


20200911092320666.png

singleton vs prototype


spring容器在启动的时候就已经将singleton的bean 缓存到 单例池中,而 prototype类型的bean ,在spring容器启动的时候并不会被实例化,仅在调用的时候生成,且每次都一个新的对象 。

看个演示20200911095006795.png


加个断点,

可以发现 还没执行到ac.getBean(B.class),仅在容器启动阶段就已经实例化完成了singleton作用域的bean。

20200911095209116.png


接下来我们看下prototype类型的bean


20200911095236463.png


可以看到 在spring容器启动的时候,并没有实例化prototype类型的bean 。


2020091109540837.png

20200911095530349.png

Singleton VS Prototype 小结


我们看到了 Singleton VS Prototype的区别

  1. 创建时机不同: singleton的bean是在容器初始化的时候创建的,而原型bean是在调用的时候创建的
  1. 作用域不同: 单例singleton的bean 在容器中仅会创建一次,并且只有一个,而原型Prototype类型的bean每次调用都会初始化一个新的对象。


下文


下文我们探讨对象和bean的关系

相关文章
|
22天前
|
设计模式 Java 开发者
如何快速上手【Spring AOP】?从动态代理到源码剖析(下篇)
Spring AOP的实现本质上依赖于代理模式这一经典设计模式。代理模式通过引入代理对象作为目标对象的中间层,实现了对目标对象访问的控制与增强,其核心价值在于解耦核心业务逻辑与横切关注点。在框架设计中,这种模式广泛用于实现功能扩展(如远程调用、延迟加载)、行为拦截(如权限校验、异常处理)等场景,为系统提供了更高的灵活性和可维护性。
|
5月前
|
前端开发 Java 物联网
智慧班牌源码,采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署
智慧班牌系统是一款基于信息化与物联网技术的校园管理工具,集成电子屏显示、人脸识别及数据交互功能,实现班级信息展示、智能考勤与家校互通。系统采用Java + Spring Boot后端框架,搭配Vue2前端技术,支持SaaS云部署与私有化定制。核心功能涵盖信息发布、考勤管理、教务处理及数据分析,助力校园文化建设与教学优化。其综合性和可扩展性有效打破数据孤岛,提升交互体验并降低管理成本,适用于日常教学、考试管理和应急场景,为智慧校园建设提供全面解决方案。
371 70
|
10月前
|
监控 Java 应用服务中间件
高级java面试---spring.factories文件的解析源码API机制
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置、起步依赖和内嵌服务器等特性,极大地简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是spring.factories文件的解析源码API机制。
253 2
|
10月前
|
监控 Java 应用服务中间件
Spring Boot整合Tomcat底层源码分析
【11月更文挑战第20天】Spring Boot是一个用于快速构建基于Spring框架的应用程序的开源框架。它通过自动配置和起步依赖等特性,大大简化了Spring应用的开发和部署过程。本文将深入探讨Spring Boot的背景历史、业务场景、功能点以及底层原理,并通过Java代码手写模拟Spring Boot的启动过程,特别是其与Tomcat的整合。
255 1
|
6月前
|
存储 监控 数据可视化
SaaS云计算技术的智慧工地源码,基于Java+Spring Cloud框架开发
智慧工地源码基于微服务+Java+Spring Cloud +UniApp +MySql架构,利用传感器、监控摄像头、AI、大数据等技术,实现施工现场的实时监测、数据分析与智能决策。平台涵盖人员、车辆、视频监控、施工质量、设备、环境和能耗管理七大维度,提供可视化管理、智能化报警、移动智能办公及分布计算存储等功能,全面提升工地的安全性、效率和质量。
109 0
|
8月前
|
监控 Java 应用服务中间件
SpringBoot是如何简化Spring开发的,以及SpringBoot的特性以及源码分析
Spring Boot 通过简化配置、自动配置和嵌入式服务器等特性,大大简化了 Spring 应用的开发过程。它通过提供一系列 `starter` 依赖和开箱即用的默认配置,使开发者能够更专注于业务逻辑而非繁琐的配置。Spring Boot 的自动配置机制和强大的 Actuator 功能进一步提升了开发效率和应用的可维护性。通过对其源码的分析,可以更深入地理解其内部工作机制,从而更好地利用其特性进行开发。
262 6
|
9月前
|
设计模式 XML Java
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
本文详细介绍了Spring框架的核心功能,并通过手写自定义Spring框架的方式,深入理解了Spring的IOC(控制反转)和DI(依赖注入)功能,并且学会实际运用设计模式到真实开发中。
【23种设计模式·全精解析 | 自定义Spring框架篇】Spring核心源码分析+自定义Spring的IOC功能,依赖注入功能
|
8月前
|
监控 JavaScript 数据可视化
建筑施工一体化信息管理平台源码,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
智慧工地云平台是专为建筑施工领域打造的一体化信息管理平台,利用大数据、云计算、物联网等技术,实现施工区域各系统数据汇总与可视化管理。平台涵盖人员、设备、物料、环境等关键因素的实时监控与数据分析,提供远程指挥、决策支持等功能,提升工作效率,促进产业信息化发展。系统由PC端、APP移动端及项目、监管、数据屏三大平台组成,支持微服务架构,采用Java、Spring Cloud、Vue等技术开发。
294 7
|
9月前
|
存储 缓存 Java
Spring面试必问:手写Spring IoC 循环依赖底层源码剖析
在Spring框架中,IoC(Inversion of Control,控制反转)是一个核心概念,它允许容器管理对象的生命周期和依赖关系。然而,在实际应用中,我们可能会遇到对象间的循环依赖问题。本文将深入探讨Spring如何解决IoC中的循环依赖问题,并通过手写源码的方式,让你对其底层原理有一个全新的认识。
200 2