Spring底层源码分析

SpringIOC加载流程

1.扫描
org.springframework.context.annotation.ClassPathBeanDefinitionScanner#doScan

根据传进来的包路径,扫描这个路径下的所有.class文件,得到一个资源数组(Resource []), 然后遍历这个资源数组,得到每个.class文件的类信息;

然后判断这个类上面是否有@Component注解,如果有就会生成一个BeanDefinition并且添加到Set集合中

org.springframework.context.annotation.ClassPathScanningCandidateComponentProvider#scanCandidateComponents

2.遍历BeanDefinition

(对这个BeanDefinition做进一步定义信息完善)

遍历每一个BeanDefinition,然后解析这个Bean的作用域,生成Bean的名称 判断是否继承了AbstractBeanDefinition,如果继承了就设置BeanDefinition的默认值,判断是否能被用来做依赖注入 判断是否继承了AnnotatedBeanDefinition,然后解析@Lazy、@Primary、@DependsOn、@Role、@Description,根据这些注解的信息,给BeanDefiniton的属性赋值

判断Spring容器是否存在这个beanName, 不存在就new一个BeanDefinitionHolder,并且添加到注册表中

3.实例化前
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#resolveBeforeInstantiation

Spring在实例化前提供了一个扩展点,因此在实例化前会判断我们是否自己实现了InstantiationAwareBeanPostProcessor接口,如果实现了就会调用我们实现的方式InstantiationAwareBeanPostProcessor.postProcessBeforeInstantiation()

4.实例化
实例化:org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#doCreateBean

首先判断BeanDefinition中是否设置了Supplier,如果设置了则调用Supplier的get()得到对象,然后直接返回

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#obtainFromSupplier

如果没有设置Supplier,就会判断是否设置了factoryMethodName,如果实现了就调用工厂得到对象

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#obtainFromSupplier

如果都没有,那就开始推断出使用哪个构造方法进行实例化对象了(推断构造方法),比如AutowiredAnnotationBeanPostProcessor会把加了@Autowired注解的构造方法找出来:

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#determineConstructorsFromBeanPostProcessors

5.实例化后

BeanDefinition 后置处理器,如果我们实现了MergedBeanDefinitionPostProcessor接口,那在实例后会调用MergedBeanDefinitionPostProcessor.postProcessMergedBeanDefinition()

@Component
public class MyMergedBeanDefinitionPostProcessor implements MergedBeanDefinitionPostProcessor {
​
  @Override
  public void postProcessMergedBeanDefinition(RootBeanDefinition beanDefinition, Class<?> beanType, String beanName) {
    if ("userService".equals(beanName)) {
      beanDefinition.getPropertyValues().add("orderService", new OrderService());
    }
  }
}

Spring会在对象实例化后,判断这个对象是否是单例、是否允许循环依赖、是否正在创建这个单例,三个条件都成立,就会将这个对象缓存到三级缓存(earlySingletonObjects)中,主要是为了解决循环依赖

Map<beanName, lambda表达式>:最后可能会生成普通对象或者是代理对象,看这个Bean是否需要AOP决定
org.springframework.beans.factory.support.DefaultSingletonBeanRegistry#addSingletonFactory

实例化后,依赖注入之前:Spring会继续判断我们是否实现了 InstantiationAwareBeanPostProcessor接口,如果实现了,那就会回调InstantiationAwareBeanPostProcessor.postProcessAfterInstantiation(),我们甚至可以在此实现自己的属性注入操作

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean

image-20240725125442576

6.依赖注入(属性填充)
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#populateBean
  org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#buildAutowiringMetadata

寻找注入点:找出当前对象的注入点并且缓存起来(所有被@Autowired注解了的field 和 method)

// 寻找@Autowired注解
org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor#postProcessProperties
// 寻找@Resource注解
org.springframework.context.annotation.CommonAnnotationBeanPostProcessor#postProcessProperties

如果注入点的类型String,Number等类型就不会进行依赖注入

遍历属性:遍历这个类的所有属性 field上是否存在@Autowired@Value@Inject*qi其中任意一个,如果有,判断这个属性是否是被static修饰,如果是也不会进行依赖注入

遍历方法

遍历这个类的所有方法method

判断这个方法是否是个桥接方法,如果是,会找出原方法

判断是否存在@Autowired@Value、@Inject 其中任意一个,如果有,

判断这个方法是否是被static修饰,如果是也不会进行依赖注入

将方法信息构造成一个AutowiredMethodElement对象,作为一个注入点对象添加到currElements集合中

找出注入点之后,遍历每个注入点,然后进行注入

org.springframework.beans.factory.annotation.InjectionMetadata#inject

7.执行Aware回调

完成了属性赋值之后,Spring会执行一些回调,包括:

BeanNameAware:回传beanName给bean对象。

BeanClassLoaderAware:回传classLoader给bean对象。

BeanFactoryAware:回传beanFactory给对象。

8.初始化前-1
org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsBeforeInitialization

Spring在初始化前提供了一个扩展点,如果我们实现了BeanPostProcessor接口,那在初始化前会调用postProcessBeforeInitialization()方法,我们可以对已经依赖注入的了bean进行处理

if (mbd == null || !mbd.isSynthetic()) {
      wrappedBean = applyBeanPostProcessorsBeforeInitialization(wrappedBean, beanName);
}

处理@PostConstruct注解初始化前会回调这个类添加了@PostConstruct的方法

org.springframework.beans.factory.annotation.InitDestroyAnnotationBeanPostProcessor#postProcessBeforeInitialization 

9.初始化

判断当前bean是否实现了InitializingBean接口,如果实现了就调用其afterPropertiesSet()方法

执行BeanDefinition中指定的初始化方法(反射调用)

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#invokeInitMethods

10.初始化后-1

Spring在初始化后会调用 BeanPostProcessor.postProcessAfterInitialization()

可以在这个步骤中,对Bean最终进行处理,Spring中的AOP就是基于初始化后实现的,初始化后返回的对象才是最终的Bean对象

org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory#applyBeanPostProcessorsAfterInitialization
  • 56
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Spring 是一个非常流行的开源框架,它提供了许多功能强大的模块和工具,使得 Java 应用程序的开发变得更加容易和高效。Spring底层原理和源码分析是理解 Spring 框架的关键。 Spring底层原理主要包括以下几个方面: 1. IoC(Inverse of Control,控制反转)容器:SpringIoC 容器负责管理应用程序中的所有对象,包括创建、初始化、配置和销毁等操作。它通过依赖注入(Dependency Injection,DI)的方式将对象之间的依赖关系进行管理,实现了对象的松耦合和可重用性。 2. AOP(Aspect Oriented Programming,面向切面编程)框架:Spring 的 AOP 框架允许在应用程序中定义切面(Aspect),并将它们与其他对象进行织入(Weaving),从而实现横切关注点(Cross-Cutting Concerns)的统一处理,如事务管理、日志记录、安全控制等。 3. JDBC(Java Database Connectivity,Java 数据库连接)框架:Spring 的 JDBC 框架提供了一组简单、易用的 API,使得 Java 应用程序可以方便地访问和操作数据库,同时还支持事务管理、异常处理等功能。 4. MVC(Model-View-Controller,模型-视图-控制器)框架:Spring 的 MVC 框架提供了一种基于 MVC 设计模式的 Web 应用程序开发方式,它将请求和响应的处理分离,使得应用程序的逻辑层和视图层更加清晰和易于维护。 对于 Spring 框架的源码分析,可以从以下几个方面进行深入研究: 1. IoC 容器的实现原理:了解 Spring IoC 容器的实现原理,包括 Bean 的加载、实例化、属性注入、生命周期管理等方面,可以更好地掌握 Spring 的核心功能。 2. AOP 框架的实现原理:研究 Spring AOP 框架的实现原理,包括切面的定义、切点的匹配、通知的织入等方面,可以深入理解 AOP 技术的本质和应用。 3. JDBC 框架的实现原理:探究 Spring JDBC 框架的实现原理,包括数据源的配置、SQL 语句的生成、结果集的处理等方面,可以理解 JDBC 技术的底层实现和优化。 4. MVC 框架的实现原理:了解 Spring MVC 框架的实现原理,包括请求的处理流程、控制器的注册和映射、视图的解析和渲染等方面,可以深入了解 Web 应用程序的开发和优化。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值